Commit 05738af3 authored by Luke Bennett's avatar Luke Bennett Committed by Luke Bennett

Improve project service desk settings

Prioritize and simplify project settings content.
parent 501ee081
<script> <script>
import Flash from '~/flash'; import Flash from '~/flash';
import { __ } from '~/locale';
import serviceDeskSetting from './service_desk_setting.vue'; import serviceDeskSetting from './service_desk_setting.vue';
import ServiceDeskStore from '../stores/service_desk_store'; import ServiceDeskStore from '../stores/service_desk_store';
import ServiceDeskService from '../services/service_desk_service'; import ServiceDeskService from '../services/service_desk_service';
...@@ -65,14 +66,14 @@ export default { ...@@ -65,14 +66,14 @@ export default {
.then(data => { .then(data => {
const email = data.service_desk_address; const email = data.service_desk_address;
if (!email) { if (!email) {
throw new Error("Response didn't include `service_desk_address`"); throw new Error(__("Response didn't include `service_desk_address`"));
} }
this.store.setIncomingEmail(email); this.store.setIncomingEmail(email);
}) })
.catch(() => { .catch(() => {
this.flash = new Flash( this.flash = Flash(
'An error occurred while fetching the Service Desk address.', __('An error occurred while fetching the Service Desk address.'),
'alert', 'alert',
this.$el, this.$el,
); );
...@@ -83,7 +84,8 @@ export default { ...@@ -83,7 +84,8 @@ export default {
this.isEnabled = isChecked; this.isEnabled = isChecked;
this.store.resetIncomingEmail(); this.store.resetIncomingEmail();
if (this.flash) { if (this.flash) {
this.flash.destroy(); this.flash.remove();
this.flash = undefined;
} }
this.service this.service
...@@ -92,18 +94,17 @@ export default { ...@@ -92,18 +94,17 @@ export default {
.then(data => { .then(data => {
const email = data.service_desk_address; const email = data.service_desk_address;
if (isChecked && !email) { if (isChecked && !email) {
throw new Error("Response didn't include `service_desk_address`"); throw new Error(__("Response didn't include `service_desk_address`"));
} }
this.store.setIncomingEmail(email); this.store.setIncomingEmail(email);
}) })
.catch(() => { .catch(() => {
const verb = isChecked ? 'enabling' : 'disabling'; const message = isChecked
this.flash = new Flash( ? __('An error occurred while enabling Service Desk.')
`An error occurred while ${verb} Service Desk.`, : __('An error occurred while disabling Service Desk.');
'alert',
this.$el, this.flash = Flash(message, 'alert', this.$el);
);
}); });
}, },
}, },
......
<script> <script>
import Toggle from '~/vue_shared/components/toggle_button.vue';
import tooltip from '~/vue_shared/directives/tooltip'; import tooltip from '~/vue_shared/directives/tooltip';
import ClipboardButton from '~/vue_shared/components/clipboard_button.vue'; import ClipboardButton from '~/vue_shared/components/clipboard_button.vue';
import eventHub from '../event_hub'; import eventHub from '../event_hub';
...@@ -11,6 +12,7 @@ export default { ...@@ -11,6 +12,7 @@ export default {
components: { components: {
ClipboardButton, ClipboardButton,
Toggle,
}, },
props: { props: {
...@@ -25,8 +27,7 @@ export default { ...@@ -25,8 +27,7 @@ export default {
}, },
}, },
methods: { methods: {
onCheckboxToggle(e) { onCheckboxToggle(isChecked) {
const isChecked = e.target.checked;
eventHub.$emit('serviceDeskEnabledCheckboxToggled', isChecked); eventHub.$emit('serviceDeskEnabledCheckboxToggled', isChecked);
}, },
}, },
...@@ -35,44 +36,45 @@ export default { ...@@ -35,44 +36,45 @@ export default {
<template> <template>
<div> <div>
<div class="form-check"> <toggle
<label for="service-desk-enabled-checkbox"> id="service-desk-checkbox"
<input ref="service-desk-checkbox"
id="service-desk-enabled-checkbox" :value="isEnabled"
ref="enabled-checkbox" class="d-inline-block align-middle mr-1"
:checked="isEnabled" @change="onCheckboxToggle"
type="checkbox"
@change="onCheckboxToggle($event)"
/> />
<span class="descr"> Activate Service Desk </span> <label class="font-weight-bold" for="service-desk-checkbox">
{{ __('Activate Service Desk') }}
</label> </label>
</div> <div v-if="isEnabled" class="row mt-3">
<div v-if="isEnabled" class="panel-slim "> <div class="col-md-9 mb-0">
<div class="card-header"> <strong id="incoming-email-describer" class="d-block mb-1">
<h3 class="card-title">Forward external support email address to:</h3> {{ __('Forward external support email address to') }}
</div> </strong>
<div class="card-body">
<template v-if="incomingEmail"> <template v-if="incomingEmail">
<span ref="service-desk-incoming-email"> {{ incomingEmail }} </span> <div class="input-group">
<input
ref="service-desk-incoming-email"
type="text"
class="form-control incoming-email h-auto"
placeholder="__('Incoming email')"
aria-label="__('Incoming email')"
aria-describedby="incoming-email-describer"
:value="incomingEmail"
disabled="true"
/>
<div class="input-group-append">
<clipboard-button <clipboard-button
:title="__('Copy incoming email address to clipboard')" :title="__('Copy to clipboard')"
:text="incomingEmail" :text="incomingEmail"
css-class="btn btn-clipboard btn-transparent" css-class="btn qa-clipboard-button"
/> />
<a </div>
href="https://docs.gitlab.com/ee/development/emails.html#email-namespace" </div>
target="_blank"
rel="noopener"
>
<i
class="fa fa-question-circle"
:aria-label="__('Learn more about incoming email addresses')"
></i>
</a>
</template> </template>
<template v-else> <template v-else>
<i class="fa fa-spinner fa-spin" aria-hidden="true"> </i> <i class="fa fa-spinner fa-spin" aria-hidden="true"> </i>
<span class="sr-only"> Fetching incoming email </span> <span class="sr-only">{{ __('Fetching incoming email') }}</span>
</template> </template>
</div> </div>
</div> </div>
......
...@@ -5,9 +5,8 @@ ...@@ -5,9 +5,8 @@
%h4.settings-title.js-settings-toggle.js-settings-toggle-trigger-only= _('Service Desk') %h4.settings-title.js-settings-toggle.js-settings-toggle-trigger-only= _('Service Desk')
%button.btn.js-settings-toggle %button.btn.js-settings-toggle
= expanded ? _('Collapse') : _('Expand') = expanded ? _('Collapse') : _('Expand')
%p - link_start = "<a href='#{help_page_path('user/project/service_desk')}' target='_blank' rel='noopener noreferrer'>".html_safe
Customize your service desk settings. %p= _('Enable/disable your service desk. %{link_start}Learn more about service desk%{link_end}.').html_safe % { link_start: link_start, link_end: '</a>'.html_safe }
= link_to "Learn more about service desk.", help_page_path('user/project/service_desk'), target: '_blank'
.settings-content .settings-content
- if EE::Gitlab::ServiceDesk.enabled?(project: @project) - if EE::Gitlab::ServiceDesk.enabled?(project: @project)
.js-service-desk-setting-root{ data: { endpoint: project_service_desk_path(@project), .js-service-desk-setting-root{ data: { endpoint: project_service_desk_path(@project),
......
---
title: Improve project service desk settings
merge_request: 10381
author:
type: other
...@@ -18,15 +18,15 @@ describe 'Service Desk Setting', :js do ...@@ -18,15 +18,15 @@ describe 'Service Desk Setting', :js do
end end
it 'shows activation checkbox' do it 'shows activation checkbox' do
expect(page).to have_selector("#service-desk-enabled-checkbox") expect(page).to have_selector("#service-desk-checkbox")
end end
it 'shows incoming email after activating' do it 'shows incoming email after activating' do
find("#service-desk-enabled-checkbox").click find("#service-desk-checkbox").click
wait_for_requests wait_for_requests
project.reload project.reload
expect(project.service_desk_enabled).to be_truthy expect(project.service_desk_enabled).to be_truthy
expect(project.service_desk_address).to be_present expect(project.service_desk_address).to be_present
expect(find('.js-service-desk-setting-wrapper .card-body')).to have_content(project.service_desk_address) expect(find('.incoming-email').value).to eq(project.service_desk_address)
end end
end end
...@@ -28,7 +28,9 @@ describe('ServiceDeskSetting', () => { ...@@ -28,7 +28,9 @@ describe('ServiceDeskSetting', () => {
}); });
it('should see activation checkbox (not disabled)', () => { it('should see activation checkbox (not disabled)', () => {
expect(vm.$refs['enabled-checkbox'].getAttribute('disabled')).toEqual(null); const checkbox = vm.$refs['service-desk-checkbox'].$el;
expect(checkbox.querySelector('.project-feature-toggle:not(.is-checked)')).toEqual(null);
}); });
it('should see main panel with the email info', () => { it('should see main panel with the email info', () => {
...@@ -56,29 +58,17 @@ describe('ServiceDeskSetting', () => { ...@@ -56,29 +58,17 @@ describe('ServiceDeskSetting', () => {
}); });
it('should see email', () => { it('should see email', () => {
expect(vm.$refs['service-desk-incoming-email'].textContent.trim()).toEqual(incomingEmail); expect(vm.$refs['service-desk-incoming-email'].value.trim()).toEqual(incomingEmail);
expect(vm.$el.querySelector('.fa-spinner')).toBeNull(); expect(vm.$el.querySelector('.fa-spinner')).toBeNull();
expect(vm.$el.querySelector('.fa-exclamation-circle')).toBeNull(); expect(vm.$el.querySelector('.fa-exclamation-circle')).toBeNull();
}); });
it('renders a copy to clipboard button', () => { it('renders a copy to clipboard button', () => {
const button = vm.$el.querySelector('.btn-clipboard'); const button = vm.$el.querySelector('.qa-clipboard-button');
expect(button).not.toBe(null); expect(button).not.toBe(null);
expect(button.dataset.clipboardText).toBe(incomingEmail); expect(button.dataset.clipboardText).toBe(incomingEmail);
}); });
it('renders a help question icon which links to gitlab docs', () => {
const link = vm.$el.querySelector('.card-body a');
expect(link).not.toBeNull();
expect(link.href).toContain('docs.gitlab.com');
const icon = link.querySelector('i.fa-question-circle');
expect(icon).not.toBeNull();
});
}); });
}); });
...@@ -121,22 +111,14 @@ describe('ServiceDeskSetting', () => { ...@@ -121,22 +111,14 @@ describe('ServiceDeskSetting', () => {
it('when getting checked', () => { it('when getting checked', () => {
expect(onCheckboxToggleSpy).not.toHaveBeenCalled(); expect(onCheckboxToggleSpy).not.toHaveBeenCalled();
vm.onCheckboxToggle({ vm.onCheckboxToggle(true);
target: {
checked: true,
},
});
expect(onCheckboxToggleSpy).toHaveBeenCalledWith(true); expect(onCheckboxToggleSpy).toHaveBeenCalledWith(true);
}); });
it('when getting unchecked', () => { it('when getting unchecked', () => {
expect(onCheckboxToggleSpy).not.toHaveBeenCalled(); expect(onCheckboxToggleSpy).not.toHaveBeenCalled();
vm.onCheckboxToggle({ vm.onCheckboxToggle(false);
target: {
checked: false,
},
});
expect(onCheckboxToggleSpy).toHaveBeenCalledWith(false); expect(onCheckboxToggleSpy).toHaveBeenCalledWith(false);
}); });
......
...@@ -485,6 +485,9 @@ msgstr "" ...@@ -485,6 +485,9 @@ msgstr ""
msgid "Action to take when receiving an alert." msgid "Action to take when receiving an alert."
msgstr "" msgstr ""
msgid "Activate Service Desk"
msgstr ""
msgid "Active" msgid "Active"
msgstr "" msgstr ""
...@@ -880,12 +883,18 @@ msgstr "" ...@@ -880,12 +883,18 @@ msgstr ""
msgid "An error occurred while detecting host keys" msgid "An error occurred while detecting host keys"
msgstr "" msgstr ""
msgid "An error occurred while disabling Service Desk."
msgstr ""
msgid "An error occurred while dismissing the alert. Refresh the page and try again." msgid "An error occurred while dismissing the alert. Refresh the page and try again."
msgstr "" msgstr ""
msgid "An error occurred while dismissing the feature highlight. Refresh the page and try dismissing again." msgid "An error occurred while dismissing the feature highlight. Refresh the page and try dismissing again."
msgstr "" msgstr ""
msgid "An error occurred while enabling Service Desk."
msgstr ""
msgid "An error occurred while fetching markdown preview" msgid "An error occurred while fetching markdown preview"
msgstr "" msgstr ""
...@@ -898,6 +907,9 @@ msgstr "" ...@@ -898,6 +907,9 @@ msgstr ""
msgid "An error occurred while fetching stages." msgid "An error occurred while fetching stages."
msgstr "" msgstr ""
msgid "An error occurred while fetching the Service Desk address."
msgstr ""
msgid "An error occurred while fetching the job log." msgid "An error occurred while fetching the job log."
msgstr "" msgstr ""
...@@ -2996,9 +3008,6 @@ msgstr "" ...@@ -2996,9 +3008,6 @@ msgstr ""
msgid "Copy file path to clipboard" msgid "Copy file path to clipboard"
msgstr "" msgstr ""
msgid "Copy incoming email address to clipboard"
msgstr ""
msgid "Copy link" msgid "Copy link"
msgstr "" msgstr ""
...@@ -3784,6 +3793,9 @@ msgstr "" ...@@ -3784,6 +3793,9 @@ msgstr ""
msgid "Enable usage ping to get an overview of how you are using GitLab from a feature perspective." msgid "Enable usage ping to get an overview of how you are using GitLab from a feature perspective."
msgstr "" msgstr ""
msgid "Enable/disable your service desk. %{link_start}Learn more about service desk%{link_end}."
msgstr ""
msgid "Enabled" msgid "Enabled"
msgstr "" msgstr ""
...@@ -4438,6 +4450,9 @@ msgstr "" ...@@ -4438,6 +4450,9 @@ msgstr ""
msgid "February" msgid "February"
msgstr "" msgstr ""
msgid "Fetching incoming email"
msgstr ""
msgid "Fields on this page are now uneditable, you can configure" msgid "Fields on this page are now uneditable, you can configure"
msgstr "" msgstr ""
...@@ -4611,6 +4626,9 @@ msgstr "" ...@@ -4611,6 +4626,9 @@ msgstr ""
msgid "Format" msgid "Format"
msgstr "" msgstr ""
msgid "Forward external support email address to"
msgstr ""
msgid "Found errors in your %{gitlab_ci_yml}:" msgid "Found errors in your %{gitlab_ci_yml}:"
msgstr "" msgstr ""
...@@ -6147,9 +6165,6 @@ msgstr "" ...@@ -6147,9 +6165,6 @@ msgstr ""
msgid "Learn more about group-level project templates" msgid "Learn more about group-level project templates"
msgstr "" msgstr ""
msgid "Learn more about incoming email addresses"
msgstr ""
msgid "Learn more about signing commits" msgid "Learn more about signing commits"
msgstr "" msgstr ""
...@@ -8763,6 +8778,9 @@ msgstr "" ...@@ -8763,6 +8778,9 @@ msgstr ""
msgid "Response" msgid "Response"
msgstr "" msgstr ""
msgid "Response didn't include `service_desk_address`"
msgstr ""
msgid "Response metrics (AWS ELB)" msgid "Response metrics (AWS ELB)"
msgstr "" msgstr ""
......
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