TT#20311 Customer wants to send a fax

What has been done:
- TT#34863, Global: Implement vuex store actions, mutations and getters
- TT#34864, Global: Implement vue components
- TT#34862, Global: Implement api requests

Change-Id: Ib547cc125271222d005ca131113086739ae3220f
changes/17/20217/9
raxelsen 8 years ago
parent 6c012fe2e5
commit d3211cb5a0

@ -104,6 +104,15 @@ Now you can log in to csc with one of the normal subscriber you just created. UR
`https://<your-ip-address>/csc`
### Send Fax
You need to first enable faxserver and activate it for the subscriber, to be able to send a fax via the "action button menu".
1. By default, vagrant-ngcp has faxserver enabled by default in the config, so currently we do not need to make any changes here. Otherwise, it would be enabled via /etc/ngcp-config/config.yml by setting "faxserver: enable:" to "yes" and applying the changes with ngcpcfg apply 'enable faxserver'""
1. Log in to ngcp-panel with administrator credentials
1. Go to Settings > Subscribers > Details > Preferences > Fax Features > Fax2Mail and SendFax, and set Active to "yes"
1. Additionally, the visibility of the fax option in "action button menu" is reliant on store state "sendFax: true" in src/store/user.js. This means it can be toggled off in the code as well if neeeded
### How to add new npm package
1. Remove the package if you've already installed it

@ -0,0 +1,17 @@
import Vue from 'vue';
export function createFax(options, subscriberId) {
return new Promise((resolve, reject) => {
let headers = {
'Content-Type': 'application/json',
};
let mergedParams = Object.assign(options, subscriberId);
let payload = JSON.stringify(mergedParams);
Vue.http.post('/api/faxes/', payload, { headers: headers }).then(() => {
resolve();
}).catch((err)=>{
reject(err);
});
});
}

@ -0,0 +1,115 @@
<template>
<q-modal v-model="showFaxModal" :minimized="!isMobile" :maximized="isMobile" id="fax-modal">
<!--NOTE: There is an issue with q-modal, mentioned in Quasar Framework documentation,-->
<!--where closing the modal by setting v-model to false, might not work properly in-->
<!--development if source files are updated while Modal is open. Best procedure is to-->
<!--always close modal before updating sourcefile (which triggers webpack re-build)-->
<div class="title">
{{ $t('communication.sendFax') }}
</div>
<q-field>
<q-input
type="text"
v-model="form.destination"
:float-label="$t('communication.label.destination')" />
</q-field>
<q-field>
<q-select
v-model="form.quality"
:options="qualityOptions"
:float-label="$t('communication.label.quality')" />
</q-field>
<q-field>
<q-input
type="text"
v-model="form.pageheader"
:float-label="$t('communication.label.pageHeader')" />
</q-field>
<q-field>
<q-input
type="textarea"
:max-height="100"
:min-rows="10"
v-model="form.data"
:float-label="$t('communication.label.content')" />
</q-field>
<q-btn flat dark @click="hideModal">{{ $t('communication.cancel') }}</q-btn>
<q-btn flat color="primary" @click="sendFax" icon-right="insert drive file" :disable="formDisabled">{{ $t('communication.send') }}</q-btn>
</q-modal>
</template>
<script>
import {
QModal,
QBtn,
QField,
QSelect,
QInput,
} from 'quasar-framework'
export default {
name: 'csc-send-fax',
data () {
return {
showFaxModal: false,
form: {
destination: null,
pageheader: null,
data: null,
quality: 'normal'
},
qualityOptions: [
{ label: this.$t('communication.quality.normal'), value: 'normal' },
{ label: this.$t('communication.quality.fine'), value: 'fine' },
{ label: this.$t('communication.quality.super'), value: 'super' }
],
isMobile: this.$q.platform.is.mobile
}
},
components: {
QModal,
QBtn,
QField,
QSelect,
QInput
},
computed: {
formDisabled() {
return !(this.form.destination &&
this.form.data && this.form.quality) ? true : false;
}
},
methods: {
sendFax() {
this.$store.dispatch('communication/createFax', this.form);
},
showModal() {
this.form = {
destination: null,
pageheader: null,
data: null,
quality: 'normal'
};
this.showFaxModal = true;
},
hideModal() {
this.showFaxModal = false;
}
}
}
</script>
<style lang="stylus" rel="stylesheet/stylus">
@import '../themes/quasar.variables.styl'
#fax-modal
.modal-content
min-width 40vw
padding 20px 15px
.title
color $primary
line-height $csc-subtitle-line-height
font-size $csc-subtitle-font-size
font-weight $csc-subtitle-font-weight
</style>

@ -91,7 +91,7 @@
<router-view />
<q-fixed-position id="global-action-btn" corner="top-right" :offset="fabOffset" class="page-button transition-generic">
<q-fab v-if="hasCommunicationCapabilities" color="primary" icon="question answer" active-icon="clear" direction="down" flat>
<q-fab-action v-if="hasFaxCapability && hasSendFaxFeature" color="primary" @click="" icon="fa-fax">
<q-fab-action v-if="hasFaxCapability && hasSendFaxFeature" color="primary" @click="showSendFax()" icon="fa-fax">
<q-tooltip v-if="isDesktop" anchor="center right" self="center left" :offset="[15, 0]">{{ $t('sendFax') }}</q-tooltip>
</q-fab-action>
<q-fab-action v-if="hasSmsCapability && hasSendSmsFeature" color="primary" @click="" icon="fa-send">
@ -105,14 +105,22 @@
<csc-call ref="cscCall" slot="right" @close="closeCall()" @fullscreen="toggleFullscreen()"
:fullscreen="isFullscreenEnabled" region="DE" />
<q-window-resize-observable @resize="onWindowResize" />
<csc-send-fax ref="sendFax" />
</q-layout>
</template>
<script>
import _ from 'lodash';
import { startLoading, stopLoading, showToast, enableIncomingCallNotifications} from '../../helpers/ui'
import {
startLoading,
stopLoading,
showToast,
showGlobalError,
enableIncomingCallNotifications
} from '../../helpers/ui'
import { mapState, mapGetters } from 'vuex'
import CscCall from '../CscCall'
import CscSendFax from '../CscSendFax'
import {
QLayout,
QToolbar,
@ -168,7 +176,8 @@
QTransition,
QCollapsible,
CscCall,
QWindowResizeObservable
QWindowResizeObservable,
CscSendFax
},
computed: {
...mapGetters('layout', [
@ -193,6 +202,10 @@
'userDataRequesting',
'userDataSucceeded'
]),
...mapGetters('communication', [
'createFaxState',
'createFaxError'
]),
...mapState({
isCallForward: state => _.startsWith(state.route.path, '/user/call-forward'),
isCallBlocking: state => _.startsWith(state.route.path, '/user/call-blocking'),
@ -234,6 +247,12 @@
}
},
methods: {
showSendFax() {
this.$refs.sendFax.showModal();
},
hideSendFax() {
this.$refs.sendFax.hideModal();
},
onWindowResize() {
},
toggleFullscreen() {
@ -317,6 +336,20 @@
if(value) {
showToast(this.$i18n.t('toasts.callNotAvailable'));
}
},
createFaxState(state) {
if (state === 'requesting') {
startLoading();
}
else if (state === 'failed') {
stopLoading();
showGlobalError(this.createFaxError);
}
else if (state === 'succeeded') {
stopLoading();
showToast(this.$t('communication.createFaxSuccessMessage'));
this.hideSendFax();
}
}
}
}

@ -259,5 +259,23 @@
"noDevices": "No devices created yet",
"noGroups": "No groups created yet",
"noSeats": "No seats created yet"
},
"communication": {
"sendFax": "Send Fax",
"quality": {
"normal": "Normal",
"fine": "Fine",
"super": "Super"
},
"label": {
"destination": "Destination Number",
"quality": "Quality",
"pageHeader": "Page Header",
"content": "Content"
},
"send": "Send",
"cancel": "Cancel",
"createFaxErrorMessage": "An error occured while trying to send the fax. Please try again.",
"createFaxSuccessMessage": "Sending fax completed successfully."
}
}

@ -0,0 +1,52 @@
'use strict';
import { RequestState } from './common'
import { createFax } from '../api/communication';
import { i18n } from '../i18n';
export default {
namespaced: true,
state: {
createFaxState: RequestState.button,
createFaxError: null
},
getters: {
subscriberId(state, getters, rootState, rootGetters) {
return parseInt(rootGetters['user/getSubscriberId']);
},
createFaxState(state) {
return state.createFaxState;
},
createFaxError(state) {
return state.createFaxError ||
i18n.t('communication.createFaxErrorMessage');
}
},
mutations: {
createFaxRequesting(state) {
state.createFaxState = RequestState.requesting;
state.createFaxError = null;
},
createFaxSucceeded(state) {
state.createFaxState = RequestState.succeeded;
state.createFaxError = null;
},
createFaxFailed(state, error) {
state.createFaxState = RequestState.failed;
state.createFaxError = error;
}
},
actions: {
createFax(context, options) {
context.commit('createFaxRequesting');
createFax(options, {
subscriber_id: context.getters.subscriberId
}).then(() => {
context.commit('createFaxSucceeded');
}).catch((err) => {
context.commit('createFaxFailed', err.message);
});
}
}
};

@ -10,6 +10,7 @@ import LayoutModule from './layout'
import PbxConfigModule from './pbx-config/index'
import ReminderModule from './reminder'
import UserModule from './user'
import CommunicationModule from './communication'
Vue.use(Vuex);
@ -22,6 +23,7 @@ export const store = new Vuex.Store({
layout: LayoutModule,
pbxConfig: PbxConfigModule,
reminder: ReminderModule,
user: UserModule
user: UserModule,
communication: CommunicationModule
}
});

@ -11,7 +11,7 @@ export default {
subscriber: null,
capabilities: null,
features: {
sendFax: false,
sendFax: true,
sendSms: false
},
loginRequesting: false,

Loading…
Cancel
Save