Commit 2174f407 authored by Eric Eastwood's avatar Eric Eastwood Committed by Sean McGivern

Use actual /group/project/service_desk endpoint

 - Prerender data-* attributes for endpoint, enabled, incoming_email to
   hydrate Vue component
 - Use actual /group/project/service_desk endpoint GET/PUT
parent 2b541e6c
......@@ -49,7 +49,7 @@ import BlobForkSuggestion from './blob/blob_fork_suggestion';
import UserCallout from './user_callout';
import GeoNodes from './geo_nodes';
import ServiceDeskEntry from './projects/settings_service_desk/service_desk_entry';
import ServiceDeskRoot from './projects/settings_service_desk/service_desk_root';
const ShortcutsBlob = require('./shortcuts_blob');
......@@ -230,8 +230,11 @@ const ShortcutsBlob = require('./shortcuts_blob');
shortcut_handler = new ShortcutsNavigation();
break;
case 'projects:edit':
const serviceDeskEntry = new ServiceDeskEntry(document.querySelector('.js-service-desk-setting-wrapper'));
serviceDeskEntry.init();
const el = document.querySelector('.js-service-desk-setting-root');
if (el) {
const serviceDeskRoot = new ServiceDeskRoot(el);
serviceDeskRoot.init();
}
break;
case 'projects:show':
shortcut_handler = new ShortcutsNavigation();
......
......@@ -5,7 +5,7 @@ export default {
name: 'ServiceDeskSetting',
props: {
isActivated: {
isEnabled: {
type: Boolean,
required: true,
},
......@@ -15,7 +15,7 @@ export default {
default: '',
},
fetchError: {
type: Object,
type: Error,
required: false,
default: null,
},
......@@ -48,14 +48,14 @@ export default {
<input
type="checkbox"
id="service-desk-enabled-checkbox"
:checked="isActivated"
:checked="isEnabled"
@change="onCheckboxToggle($event)">
<span class="descr">
Activate service desk
</span>
</label>
</div>
<template v-if="isActivated">
<template v-if="isEnabled">
<div
class="panel-slim panel-default">
<div class="panel-heading">
......
......@@ -5,17 +5,28 @@ import ServiceDeskStore from './stores/service_desk_store';
import ServiceDeskService from './services/service_desk_service';
import eventHub from './event_hub';
class ServiceDeskEntry {
class ServiceDeskRoot {
constructor(wrapperElement) {
this.wrapperElement = wrapperElement;
const isEnabled = this.wrapperElement.dataset.enabled !== undefined &&
this.wrapperElement.dataset.enabled !== 'false';
const incomingEmail = this.wrapperElement.dataset.incomingEmail;
const endpoint = this.wrapperElement.dataset.endpoint;
this.store = new ServiceDeskStore();
this.store = new ServiceDeskStore({
isEnabled,
incomingEmail,
});
this.service = new ServiceDeskService(endpoint);
}
init() {
this.bindEvents();
if (this.store.state.isEnabled && !this.store.state.incomingEmail) {
this.fetchIncomingEmail();
}
this.render();
}
......@@ -35,7 +46,7 @@ class ServiceDeskEntry {
data: this.store.state,
template: `
<service-desk-setting
:isActivated="isActivated"
:isEnabled="isEnabled"
:incomingEmail="incomingEmail"
:fetchError="fetchError" />
`,
......@@ -45,19 +56,28 @@ class ServiceDeskEntry {
});
}
fetchIncomingEmail() {
this.service.fetchIncomingEmail()
.then((incomingEmail) => {
this.store.setIncomingEmail(incomingEmail);
})
.catch((err) => {
this.store.setFetchError(err);
});
}
onEnableToggled(isChecked) {
this.store.setIsActivated(isChecked);
if (isChecked) {
this.store.setIncomingEmail('');
this.store.setFetchError(null);
this.service.fetchIncomingEmail()
.then((incomingEmail) => {
this.store.setIncomingEmail(incomingEmail);
})
.catch((err) => {
this.store.setFetchError(err);
});
}
this.store.setIncomingEmail('');
this.store.setFetchError(null);
this.service.toggleServiceDesk(isChecked)
.then((incomingEmail) => {
this.store.setIncomingEmail(incomingEmail);
})
.catch((err) => {
this.store.setFetchError(err);
});
}
destroy() {
......@@ -68,4 +88,4 @@ class ServiceDeskEntry {
}
}
export default ServiceDeskEntry;
export default ServiceDeskRoot;
......@@ -6,12 +6,33 @@ Vue.use(vueResource);
class ServiceDeskService {
constructor(endpoint) {
this.serviceDeskEnabledResource = Vue.resource(`${endpoint}/service_desk_address`);
this.serviceDeskResource = Vue.resource(`${endpoint}`);
}
fetchIncomingEmail() {
return this.serviceDeskEnabledResource.get()
.then(res => res.data.incomingEmail);
return this.serviceDeskResource.get()
.then((res) => {
const email = res.data.service_desk_address;
if (!email) {
throw new Error('Response didn\'t include `service_desk_address`');
}
return email;
});
}
toggleServiceDesk(enable) {
return this.serviceDeskResource.update({
service_desk_enabled: enable,
})
.then((res) => {
const email = res.data.service_desk_address;
if (enable && !email) {
throw new Error('Response didn\'t include `service_desk_address`');
}
return email;
});
}
}
......
class ServiceDeskStore {
constructor(initialState = {}) {
this.state = Object.assign({
isActivated: false,
isEnabled: false,
incomingEmail: '',
fetchError: null,
}, initialState);
}
setIsActivated(value) {
this.state.isActivated = value;
this.state.isEnabled = value;
}
setIncomingEmail(value) {
......
......@@ -126,12 +126,15 @@
= render 'merge_request_settings', form: f
%hr
%fieldset.features.append-bottom-default
%h5.prepend-top-0
Service Desk
= link_to icon('question-circle'), help_page_path("TODO")
.js-service-desk-setting-wrapper{ data: { endpoint: namespace_project_path(@project.namespace, @project), enabled: @project.service_desk_enabled?, incomingAddress: (@project.service_desk_address if @project.service_desk_enabled? ) } }
- if EE::Gitlab::ServiceDesk.enabled?
%hr
%fieldset.js-service-desk-setting-wrapper.features.append-bottom-default
%h5.prepend-top-0
Service Desk
= link_to icon('question-circle'), help_page_path("TODO")
.js-service-desk-setting-root{ data: { endpoint: namespace_project_service_desk_path(@project.namespace, @project),
enabled: @project.service_desk_enabled,
incoming_email: (@project.service_desk_address if @project.service_desk_enabled) } }
%hr
%fieldset.features.append-bottom-default
......
require 'spec_helper'
describe 'Service Desk Setting', js: true, feature: true do
include WaitForAjax
let(:project) { create(:project_empty_repo, :private) }
let(:user) { create(:user) }
before do
project.add_master(user)
login_as(user)
allow_any_instance_of(License).to receive(:add_on?).and_call_original
allow_any_instance_of(License).to receive(:add_on?).with('GitLab_ServiceDesk') { true }
visit edit_namespace_project_path(project.namespace, project)
end
it 'shows service desk activation checkbox' do
expect(page).to have_selector("#service-desk-enabled-checkbox")
end
it 'shows incoming email after activating' do
find("#service-desk-enabled-checkbox").click
wait_for_ajax
expect(find('.js-service-desk-setting-wrapper .panel-body')).to have_content(project.service_desk_address)
end
end
......@@ -19,13 +19,13 @@ describe('ServiceDeskSetting', () => {
}
});
describe('when isActivated=true', () => {
describe('when isEnabled=true', () => {
let el;
describe('only isActivated', () => {
describe('only isEnabled', () => {
beforeEach(() => {
vm = createComponent({
isActivated: true,
isEnabled: true,
});
el = vm.$el;
});
......@@ -48,7 +48,7 @@ describe('ServiceDeskSetting', () => {
describe('with incomingEmail', () => {
beforeEach(() => {
vm = createComponent({
isActivated: true,
isEnabled: true,
incomingEmail: 'foo@bar.com',
});
el = vm.$el;
......@@ -64,7 +64,7 @@ describe('ServiceDeskSetting', () => {
describe('with fetchError', () => {
beforeEach(() => {
vm = createComponent({
isActivated: true,
isEnabled: true,
fetchError: new Error('some-fake-failure'),
});
el = vm.$el;
......@@ -79,12 +79,12 @@ describe('ServiceDeskSetting', () => {
});
});
describe('when isActivated=false', () => {
describe('when isEnabled=false', () => {
let el;
beforeEach(() => {
vm = createComponent({
isActivated: false,
isEnabled: false,
});
el = vm.$el;
});
......@@ -107,7 +107,7 @@ describe('ServiceDeskSetting', () => {
eventHub.$on('serviceDeskEnabledCheckboxToggled', onCheckboxToggleSpy);
vm = createComponent({
isActivated: false,
isEnabled: false,
});
});
......@@ -139,7 +139,7 @@ describe('ServiceDeskSetting', () => {
describe('copyIncomingEmail', () => {
beforeEach(() => {
vm = createComponent({
isActivated: true,
isEnabled: true,
incomingEmail: 'foo@bar.com',
});
});
......
......@@ -8,9 +8,10 @@ describe('ServiceDeskService', () => {
});
it('fetchIncomingEmail', (done) => {
spyOn(service.project, 'get').and.returnValue(Promise.resolve({
spyOn(service.serviceDeskResource, 'get').and.returnValue(Promise.resolve({
data: {
incomingEmail: 'foo@bar.com',
service_desk_enabled: true,
service_desk_address: 'foo@bar.com',
},
}));
......@@ -23,4 +24,42 @@ describe('ServiceDeskService', () => {
done.fail(`Failed to fetch incoming email:\n${err}`);
});
});
describe('toggleServiceDesk', () => {
it('enable service desk', (done) => {
spyOn(service.serviceDeskResource, 'update').and.returnValue(Promise.resolve({
data: {
service_desk_enabled: true,
service_desk_address: 'foo@bar.com',
},
}));
service.toggleServiceDesk(true)
.then((incomingEmail) => {
expect(incomingEmail).toEqual('foo@bar.com');
done();
})
.catch((err) => {
done.fail(`Failed to enable service desk and fetch incoming email:\n${err}`);
});
});
it('disable service desk', (done) => {
spyOn(service.serviceDeskResource, 'update').and.returnValue(Promise.resolve({
data: {
service_desk_enabled: false,
service_desk_address: null,
},
}));
service.toggleServiceDesk(false)
.then((incomingEmail) => {
expect(incomingEmail).toEqual(null);
done();
})
.catch((err) => {
done.fail(`Failed to disable service desk and reset incoming email:\n${err}`);
});
});
});
});
......@@ -9,19 +9,19 @@ describe('ServiceDeskStore', () => {
describe('setIsActivated', () => {
it('defaults to false', () => {
expect(store.state.isActivated).toEqual(false);
expect(store.state.isEnabled).toEqual(false);
});
it('set true', () => {
store.setIsActivated(true);
expect(store.state.isActivated).toEqual(true);
expect(store.state.isEnabled).toEqual(true);
});
it('set false', () => {
store.setIsActivated(false);
expect(store.state.isActivated).toEqual(false);
expect(store.state.isEnabled).toEqual(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