[Enhancement] Add ApiClient, refactor CannedResponse (#183)

This commit is contained in:
Pranav Raj S 2019-10-27 10:48:26 +05:30 committed by GitHub
parent 50fc06681c
commit 6c60b60240
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
10 changed files with 311 additions and 322 deletions

View file

@ -0,0 +1,31 @@
/* global axios */
const API_VERSION = `/api/v1`;
class ApiClient {
constructor(url) {
this.url = `${API_VERSION}/${url}`;
}
get() {
return axios.get(this.url);
}
show(id) {
return axios.get(`${this.url}/${id}`);
}
create(data) {
return axios.post(this.url, data);
}
update(id, data) {
return axios.patch(`${this.url}/${id}`, data);
}
delete(id) {
return axios.delete(`${this.url}/${id}`);
}
}
export default ApiClient;

View file

@ -1,112 +1,16 @@
/* eslint no-console: 0 */
/* global axios */
/* eslint no-undef: "error" */
/* eslint no-unused-expressions: ["error", { "allowShortCircuit": true }] */
import endPoints from './endPoints';
export default {
getAllCannedResponses() {
const urlData = endPoints('cannedResponse').get();
const fetchPromise = new Promise((resolve, reject) => {
axios
.get(urlData.url)
.then(response => {
resolve(response);
})
.catch(error => {
reject(Error(error));
});
});
return fetchPromise;
},
import ApiClient from './ApiClient';
searchCannedResponse({ searchKey }) {
let urlData = endPoints('cannedResponse').get();
urlData = `${urlData.url}?search=${searchKey}`;
const fetchPromise = new Promise((resolve, reject) => {
axios
.get(urlData)
.then(response => {
resolve(response);
})
.catch(error => {
reject(Error(error));
});
});
return fetchPromise;
},
class CannedResponse extends ApiClient {
constructor() {
super('canned_responses');
}
addCannedResponse(cannedResponseObj) {
const urlData = endPoints('cannedResponse').post();
const fetchPromise = new Promise((resolve, reject) => {
axios
.post(urlData.url, cannedResponseObj)
.then(response => {
resolve(response);
})
.catch(error => {
reject(Error(error));
});
});
return fetchPromise;
},
editCannedResponse(cannedResponseObj) {
const urlData = endPoints('cannedResponse').put(cannedResponseObj.id);
const fetchPromise = new Promise((resolve, reject) => {
axios
.put(urlData.url, cannedResponseObj)
.then(response => {
resolve(response);
})
.catch(error => {
reject(Error(error));
});
});
return fetchPromise;
},
deleteCannedResponse(responseId) {
const urlData = endPoints('cannedResponse').delete(responseId);
const fetchPromise = new Promise((resolve, reject) => {
axios
.delete(urlData.url)
.then(response => {
resolve(response);
})
.catch(error => {
reject(Error(error));
});
});
return fetchPromise;
},
getLabels() {
const urlData = endPoints('fetchLabels');
const fetchPromise = new Promise((resolve, reject) => {
axios
.get(urlData.url)
.then(response => {
resolve(response);
})
.catch(error => {
reject(Error(error));
});
});
return fetchPromise;
},
// Get Inbox related to the account
getInboxes() {
const urlData = endPoints('fetchInboxes');
const fetchPromise = new Promise((resolve, reject) => {
axios
.get(urlData.url)
.then(response => {
console.log('fetch inboxes success');
resolve(response);
})
.catch(error => {
console.log('fetch inboxes failure');
reject(Error(error));
});
});
return fetchPromise;
},
};
get({ searchKey }) {
const url = searchKey ? `${this.url}?search=${searchKey}` : this.url;
return axios.get(url);
}
}
export default new CannedResponse();

View file

@ -1,49 +1,71 @@
<template>
<div class="reply-box">
<div class="reply-box__top" :class="{ 'is-private': private }">
<div class="reply-box__top" :class="{ 'is-private': isPrivate }">
<canned-response
v-if="showCannedModal"
v-on-clickaway="hideCannedResponse"
data-dropdown-menu
:on-keyenter="replaceText"
:on-click="replaceText"
v-if="showCannedModal"
/>
<emoji-input v-on-clickaway="hideEmojiPicker" :on-click="emojiOnClick" v-if="showEmojiPicker"/>
<emoji-input
v-if="showEmojiPicker"
v-on-clickaway="hideEmojiPicker"
:on-click="emojiOnClick"
/>
<textarea
rows="1"
ref="messageInput"
v-model="message"
rows="1"
class="input"
type="text"
:placeholder="$t(messagePlaceHolder())"
@click="onClick()"
@blur="onBlur()"
v-bind:placeholder="$t(messagePlaceHolder())"
ref="messageInput"
/>
<i class="icon ion-happy-outline" :class="{ active: showEmojiPicker}" @click="toggleEmojiPicker()"></i>
<i
class="icon ion-happy-outline"
:class="{ active: showEmojiPicker }"
@click="toggleEmojiPicker()"
></i>
</div>
<div class="reply-box__bottom" >
<div class="reply-box__bottom">
<ul class="tabs">
<li class="tabs-title" v-bind:class="{ 'is-active': !private }">
<a href="#" @click="makeReply" >Reply</a>
<li class="tabs-title" :class="{ 'is-active': !isPrivate }">
<a href="#" @click="makeReply">Reply</a>
</li>
<li class="tabs-title is-private" v-bind:class="{ 'is-active': private }">
<li class="tabs-title is-private" :class="{ 'is-active': isPrivate }">
<a href="#" @click="makePrivate">Private Note</a>
</li>
<li class="tabs-title message-length" v-if="message.length">
<a :class="{ 'message-error': message.length > 620 }">{{ message.length }} / 640</a>
<li v-if="message.length" class="tabs-title message-length">
<a :class="{ 'message-error': message.length > 620 }">
{{ message.length }} / 640
</a>
</li>
</ul>
<button
@click="sendMessage"
type="button"
class="button send-button"
:disabled="disableButton()"
v-bind:class="{ 'disabled': message.length === 0 || message.length > 640,
'warning': private }"
:class="{
disabled: message.length === 0 || message.length > 640,
warning: isPrivate,
}"
@click="sendMessage"
>
{{ private ? $t('CONVERSATION.REPLYBOX.CREATE') : $t('CONVERSATION.REPLYBOX.SEND') }}
<i class="icon" :class="{ 'ion-android-send': !private, 'ion-android-lock': private }"></i>
{{
isPrivate
? $t('CONVERSATION.REPLYBOX.CREATE')
: $t('CONVERSATION.REPLYBOX.SEND')
}}
<i
class="icon"
:class="{
'ion-android-send': !isPrivate,
'ion-android-lock': isPrivate,
}"
></i>
</button>
</div>
</div>
@ -76,21 +98,6 @@ export default {
EmojiInput,
CannedResponse,
},
mounted() {
/* eslint-disable no-confusing-arrow */
document.addEventListener('keydown', (e) => {
if (this.isEscape(e)) {
this.hideEmojiPicker();
this.hideCannedResponse();
}
if (this.isEnter(e)) {
if (!e.shiftKey) {
e.preventDefault();
this.sendMessage();
}
}
});
},
watch: {
message(val) {
if (this.private) {
@ -103,17 +110,32 @@ export default {
this.showCannedModal = true;
if (val.length > 1) {
const searchKey = val.substr(1, val.length);
this.$store.dispatch('searchCannedResponse', {
this.$store.dispatch('getCannedResponse', {
searchKey,
});
} else {
this.$store.dispatch('fetchCannedResponse');
this.$store.dispatch('getCannedResponse');
}
} else {
this.showCannedModal = false;
}
},
},
mounted() {
/* eslint-disable no-confusing-arrow */
document.addEventListener('keydown', e => {
if (this.isEscape(e)) {
this.hideEmojiPicker();
this.hideCannedResponse();
}
if (this.isEnter(e)) {
if (!e.shiftKey) {
e.preventDefault();
this.sendMessage();
}
}
});
},
methods: {
isEnter(e) {
return e.keyCode === 13;
@ -126,9 +148,11 @@ export default {
if (messageHasOnlyNewLines) {
return;
}
const messageAction = this.private ? 'addPrivateNote' : 'sendMessage';
const messageAction = this.isPrivate ? 'addPrivateNote' : 'sendMessage';
if (this.message.length !== 0 && !this.showCannedModal) {
this.$store.dispatch(messageAction, [this.currentChat.id, this.message]).then(() => {
this.$store
.dispatch(messageAction, [this.currentChat.id, this.message])
.then(() => {
this.$emit('scrollToMessage');
});
this.clearMessage();
@ -141,15 +165,17 @@ export default {
}, 200);
},
makePrivate() {
this.private = true;
this.isPrivate = true;
this.$refs.messageInput.focus();
},
makeReply() {
this.private = false;
this.isPrivate = false;
this.$refs.messageInput.focus();
},
emojiOnClick(emoji) {
this.message = emojione.shortnameToUnicode(`${this.message}${emoji.shortname} `);
this.message = emojione.shortnameToUnicode(
`${this.message}${emoji.shortname} `
);
},
clearMessage() {
this.message = '';
@ -189,11 +215,17 @@ export default {
},
disableButton() {
const messageHasOnlyNewLines = !this.message.replace(/\n/g, '').length;
return this.message.length === 0 || this.message.length > 640 || messageHasOnlyNewLines;
return (
this.message.length === 0 ||
this.message.length > 640 ||
messageHasOnlyNewLines
);
},
messagePlaceHolder() {
const placeHolder = this.private ? 'CONVERSATION.FOOTER.PRIVATE_MSG_INPUT' : 'CONVERSATION.FOOTER.MSG_INPUT';
const placeHolder = this.isPrivate
? 'CONVERSATION.FOOTER.PRIVATE_MSG_INPUT'
: 'CONVERSATION.FOOTER.MSG_INPUT';
return placeHolder;
},
},
@ -201,7 +233,7 @@ export default {
</script>
<style lang="scss">
.send-button {
.send-button {
margin-bottom: 0;
}
}
</style>

View file

@ -6,24 +6,38 @@
:header-title="$t('CANNED_MGMT.ADD.TITLE')"
:header-content="$t('CANNED_MGMT.ADD.DESC')"
/>
<form class="row" v-on:submit.prevent="addAgent()">
<form class="row" @submit.prevent="addAgent()">
<div class="medium-12 columns">
<label :class="{ 'error': $v.shortCode.$error }">
<label :class="{ error: $v.shortCode.$error }">
{{ $t('CANNED_MGMT.ADD.FORM.SHORT_CODE.LABEL') }}
<input type="text" v-model.trim="shortCode" @input="$v.shortCode.$touch" :placeholder="$t('CANNED_MGMT.ADD.FORM.SHORT_CODE.PLACEHOLDER')">
<input
v-model.trim="shortCode"
type="text"
:placeholder="$t('CANNED_MGMT.ADD.FORM.SHORT_CODE.PLACEHOLDER')"
@input="$v.shortCode.$touch"
/>
</label>
</div>
<div class="medium-12 columns">
<label :class="{ 'error': $v.content.$error }">
<label :class="{ error: $v.content.$error }">
{{ $t('CANNED_MGMT.ADD.FORM.CONTENT.LABEL') }}
<input type="text" v-model.trim="content" @input="$v.content.$touch" :placeholder="$t('CANNED_MGMT.ADD.FORM.CONTENT.PLACEHOLDER')">
<input
v-model.trim="content"
type="text"
:placeholder="$t('CANNED_MGMT.ADD.FORM.CONTENT.PLACEHOLDER')"
@input="$v.content.$touch"
/>
</label>
</div>
<div class="modal-footer">
<div class="medium-12 columns">
<woot-submit-button
:disabled="$v.content.$invalid || $v.shortCode.$invalid || addCanned.showLoading"
:disabled="
$v.content.$invalid ||
$v.shortCode.$invalid ||
addCanned.showLoading
"
:button-text="$t('CANNED_MGMT.ADD.FORM.SUBMIT')"
:loading="addCanned.showLoading"
/>
@ -40,20 +54,17 @@
/* eslint no-console: 0 */
import { required, minLength } from 'vuelidate/lib/validators';
import PageHeader from '../SettingsSubPageHeader';
import WootSubmitButton from '../../../../components/buttons/FormSubmitButton';
import Modal from '../../../../components/Modal';
const cannedImg = require('assets/images/canned.svg');
export default {
props: ['onClose'],
components: {
PageHeader,
WootSubmitButton,
Modal,
},
props: ['onClose'],
data() {
return {
shortCode: '',
@ -97,7 +108,8 @@ export default {
bus.$emit('newToastMessage', this.addCanned.message);
},
resetForm() {
this.shortCode = this.content = '';
this.shortCode = '';
this.content = '';
this.$v.shortCode.$reset();
this.$v.content.$reset();
},
@ -105,14 +117,17 @@ export default {
// Show loading on button
this.addCanned.showLoading = true;
// Make API Calls
this.$store.dispatch('addCannedResponse', {
this.$store
.dispatch('createCannedResponse', {
short_code: this.shortCode,
content: this.content,
})
.then(() => {
// Reset Form, Show success message
this.addCanned.showLoading = false;
this.addCanned.message = this.$t('CANNED_MGMT.ADD.API.SUCCESS_MESSAGE');
this.addCanned.message = this.$t(
'CANNED_MGMT.ADD.API.SUCCESS_MESSAGE'
);
this.showAlert();
this.resetForm();
this.onClose();

View file

@ -1,13 +1,6 @@
<template>
<modal
:show.sync="show"
:on-close="onClose"
>
<woot-modal-header
:header-title="title"
:header-content="message"
/>
<modal :show.sync="show" :on-close="onClose">
<woot-modal-header :header-title="title" :header-content="message" />
<div class="modal-footer delete-item">
<button class="button" @click="onClose">
{{ rejectText }}
@ -20,13 +13,11 @@
</template>
<script>
import PageHeader from '../SettingsSubPageHeader';
import Modal from '../../../../components/Modal';
export default {
components: {
Modal,
PageHeader,
},
props: {
show: Boolean,

View file

@ -1,27 +1,39 @@
<template>
<modal :show.sync="show" :on-close="onClose">
<div class="column content-box">
<woot-modal-header
:header-title="pageTitle"
/>
<form class="row medium-8" v-on:submit.prevent="editCannedResponse()">
<woot-modal-header :header-title="pageTitle" />
<form class="row medium-8" @submit.prevent="editCannedResponse()">
<div class="medium-12 columns">
<label :class="{ 'error': $v.shortCode.$error }">
<label :class="{ error: $v.shortCode.$error }">
{{ $t('CANNED_MGMT.EDIT.FORM.SHORT_CODE.LABEL') }}
<input type="text" v-model.trim="shortCode" @input="$v.shortCode.$touch" :placeholder="$t('CANNED_MGMT.EDIT.FORM.SHORT_CODE.PLACEHOLDER')">
<input
v-model.trim="shortCode"
type="text"
:placeholder="$t('CANNED_MGMT.EDIT.FORM.SHORT_CODE.PLACEHOLDER')"
@input="$v.shortCode.$touch"
/>
</label>
</div>
<div class="medium-12 columns">
<label :class="{ 'error': $v.content.$error }">
<label :class="{ error: $v.content.$error }">
{{ $t('CANNED_MGMT.EDIT.FORM.CONTENT.LABEL') }}
<input type="text" v-model.trim="content" @input="$v.content.$touch" :placeholder="$t('CANNED_MGMT.EDIT.FORM.CONTENT.PLACEHOLDER')">
<input
v-model.trim="content"
type="text"
:placeholder="$t('CANNED_MGMT.EDIT.FORM.CONTENT.PLACEHOLDER')"
@input="$v.content.$touch"
/>
</label>
</div>
<div class="modal-footer">
<div class="medium-12 columns">
<woot-submit-button
:disabled="$v.content.$invalid || $v.shortCode.$invalid || editCanned.showLoading"
:disabled="
$v.content.$invalid ||
$v.shortCode.$invalid ||
editCanned.showLoading
"
:button-text="$t('CANNED_MGMT.EDIT.FORM.SUBMIT')"
:loading="editCanned.showLoading"
/>
@ -38,13 +50,11 @@
/* eslint no-console: 0 */
import { required, minLength } from 'vuelidate/lib/validators';
import PageHeader from '../SettingsSubPageHeader';
import WootSubmitButton from '../../../../components/buttons/FormSubmitButton';
import Modal from '../../../../components/Modal';
export default {
components: {
PageHeader,
WootSubmitButton,
Modal,
},
@ -89,7 +99,8 @@ export default {
bus.$emit('newToastMessage', this.editCanned.message);
},
resetForm() {
this.shortCode = this.content = '';
this.shortCode = '';
this.content = '';
this.$v.shortCode.$reset();
this.$v.content.$reset();
},
@ -97,7 +108,8 @@ export default {
// Show loading on button
this.editCanned.showLoading = true;
// Make API Calls
this.$store.dispatch('editCannedResponse', {
this.$store
.dispatch('updateCannedResponse', {
id: this.id,
name: this.shortCode,
content: this.content,
@ -105,7 +117,9 @@ export default {
.then(() => {
// Reset Form, Show success message
this.editCanned.showLoading = false;
this.editCanned.message = this.$t('CANNED_MGMT.EDIT.API.SUCCESS_MESSAGE');
this.editCanned.message = this.$t(
'CANNED_MGMT.EDIT.API.SUCCESS_MESSAGE'
);
this.showAlert();
this.resetForm();
setTimeout(() => {
@ -114,7 +128,9 @@ export default {
})
.catch(() => {
this.editCanned.showLoading = false;
this.editCanned.message = this.$t('CANNED_MGMT.EDIT.API.ERROR_MESSAGE');
this.editCanned.message = this.$t(
'CANNED_MGMT.EDIT.API.ERROR_MESSAGE'
);
this.showAlert();
});
},

View file

@ -11,18 +11,18 @@
<div class="row">
<div class="small-8 columns">
<p
v-if="!fetchStatus && !cannedResponseList.length"
v-if="!uiFlags.fetchingList && !records.length"
class="no-items-error-message"
>
{{ $t('CANNED_MGMT.LIST.404') }}
</p>
<woot-loading-state
v-if="fetchStatus"
v-if="uiFlags.fetchingList"
:message="$t('CANNED_MGMT.LOADING')"
/>
<table
v-if="!fetchStatus && cannedResponseList.length"
v-if="!uiFlags.fetchingList && records.length"
class="woot-table"
>
<thead>
@ -36,7 +36,7 @@
</thead>
<tbody>
<tr
v-for="(cannedItem, index) in cannedResponseList"
v-for="(cannedItem, index) in records"
:key="cannedItem.short_code"
>
<!-- Short Code -->
@ -126,8 +126,8 @@ export default {
},
computed: {
...mapGetters({
cannedResponseList: 'getCannedResponses',
fetchStatus: 'getCannedFetchStatus',
records: 'getCannedResponses',
uiFlags: 'getUIFlags',
}),
// Delete Modal
deleteConfirmText() {
@ -148,7 +148,7 @@ export default {
},
mounted() {
// Fetch API Call
this.$store.dispatch('fetchCannedResponse');
this.$store.dispatch('getCannedResponse');
},
methods: {
showAlert(message) {
@ -192,9 +192,7 @@ export default {
},
deleteCannedResponse(id) {
this.$store
.dispatch('deleteCannedResponse', {
id,
})
.dispatch('deleteCannedResponse', id)
.then(() => {
this.showAlert(this.$t('CANNED_MGMT.DELETE.API.SUCCESS_MESSAGE'));
})

View file

@ -2,108 +2,110 @@
/* eslint no-param-reassign: 0 */
/* eslint no-shadow: 0 */
import * as types from '../mutation-types';
import CannedApi from '../../api/cannedResponse';
import { setLoadingStatus, getLoadingStatus } from '../utils/api';
import CannedResponseAPI from '../../api/cannedResponse';
const state = {
cannedResponse: [],
fetchAPIloadingStatus: false,
records: [],
uiFlags: {
fetchingList: false,
fetchingItem: false,
creatingItem: false,
updatingItem: false,
deletingItem: false,
},
};
const getters = {
getCannedResponses(_state) {
return _state.cannedResponse;
return _state.records;
},
getUIFlags(_state) {
return _state.uiFlags;
},
getCannedFetchStatus: getLoadingStatus,
};
const actions = {
fetchCannedResponse({ commit }) {
commit(types.default.SET_CANNED_FETCHING_STATUS, true);
CannedApi.getAllCannedResponses()
.then(response => {
commit(types.default.SET_CANNED_FETCHING_STATUS, false);
commit(types.default.SET_CANNED, response);
})
.catch();
},
searchCannedResponse({ commit }, { searchKey }) {
commit(types.default.SET_CANNED_FETCHING_STATUS, true);
CannedApi.searchCannedResponse({ searchKey })
.then(response => {
commit(types.default.SET_CANNED_FETCHING_STATUS, false);
commit(types.default.SET_CANNED, response);
})
.catch();
},
addCannedResponse({ commit }, cannedObj) {
return new Promise((resolve, reject) => {
CannedApi.addCannedResponse(cannedObj)
.then(response => {
commit(types.default.ADD_CANNED, response);
resolve();
})
.catch(response => {
reject(response);
});
});
},
editCannedResponse({ commit }, cannedObj) {
return new Promise((resolve, reject) => {
CannedApi.editCannedResponse(cannedObj)
.then(response => {
commit(types.default.EDIT_CANNED, response, cannedObj.id);
resolve();
})
.catch(response => {
reject(response);
});
});
},
deleteCannedResponse({ commit }, responseId) {
return new Promise((resolve, reject) => {
CannedApi.deleteCannedResponse(responseId.id)
.then(response => {
if (response.status === 200) {
commit(types.default.DELETE_CANNED, responseId);
getCannedResponse: async function getCannedResponse(
{ commit },
{ searchKey } = {}
) {
commit(types.default.SET_CANNED_UI_FLAG, { fetchingList: true });
try {
const response = await CannedResponseAPI.get({ searchKey });
commit(types.default.SET_CANNED, response.data);
commit(types.default.SET_CANNED_UI_FLAG, { fetchingList: false });
} catch (error) {
commit(types.default.SET_CANNED_UI_FLAG, { fetchingList: false });
}
},
createCannedResponse: async function createCannedResponse(
{ commit },
cannedObj
) {
commit(types.default.SET_CANNED_UI_FLAG, { creatingItem: true });
try {
const response = await CannedResponseAPI.create(cannedObj);
commit(types.default.ADD_CANNED, response.data);
commit(types.default.SET_CANNED_UI_FLAG, { creatingItem: false });
} catch (error) {
commit(types.default.SET_CANNED_UI_FLAG, { creatingItem: false });
}
},
updateCannedResponse: async function updateCannedResponse(
{ commit },
{ id, ...updateObj }
) {
commit(types.default.SET_CANNED_UI_FLAG, { updatingItem: true });
try {
const response = await CannedResponseAPI.update(id, updateObj);
commit(types.default.EDIT_CANNED, response.data);
commit(types.default.SET_CANNED_UI_FLAG, { updatingItem: false });
} catch (error) {
commit(types.default.SET_CANNED_UI_FLAG, { updatingItem: false });
}
},
deleteCannedResponse: async function deleteCannedResponse({ commit }, id) {
commit(types.default.SET_CANNED_UI_FLAG, { deletingItem: true });
try {
await CannedResponseAPI.delete(id);
commit(types.default.DELETE_CANNED, id);
commit(types.default.SET_CANNED_UI_FLAG, { deletingItem: true });
} catch (error) {
commit(types.default.SET_CANNED_UI_FLAG, { deletingItem: true });
}
resolve();
})
.catch(response => {
reject(response);
});
});
},
};
const mutations = {
// List
[types.default.SET_CANNED_FETCHING_STATUS]: setLoadingStatus,
// List
[types.default.SET_CANNED](_state, response) {
_state.cannedResponse = response.data;
},
// Add Agent
[types.default.ADD_CANNED](_state, response) {
if (response.status === 200) {
_state.cannedResponse.push(response.data);
}
},
// Edit Agent
[types.default.EDIT_CANNED](_state, response) {
if (response.status === 200) {
_state.cannedResponse.forEach((element, index) => {
if (element.id === response.data.id) {
_state.cannedResponse[index] = response.data;
}
});
}
[types.default.SET_CANNED_UI_FLAG](_state, data) {
_state.uiFlags = {
..._state.uiFlags,
...data,
};
},
// Delete CannedResponse
[types.default.DELETE_CANNED](_state, { id }) {
_state.cannedResponse = _state.cannedResponse.filter(
agent => agent.id !== id
[types.default.SET_CANNED](_state, data) {
_state.records = data;
},
[types.default.ADD_CANNED](_state, data) {
_state.records.push(data);
},
[types.default.EDIT_CANNED](_state, data) {
_state.records.forEach((element, index) => {
if (element.id === data.id) {
_state.records[index] = data;
}
});
},
[types.default.DELETE_CANNED](_state, id) {
_state.records = _state.records.filter(
cannedResponse => cannedResponse.id !== id
);
},
};

View file

@ -48,7 +48,7 @@ export default {
DELETE_AGENT: 'DELETE_AGENT',
// Canned Response
SET_CANNED_FETCHING_STATUS: 'SET_CANNED_FETCHING_STATUS',
SET_CANNED_UI_FLAG: 'SET_CANNED_UI_FLAG',
SET_CANNED: 'SET_CANNED',
ADD_CANNED: 'ADD_CANNED',
EDIT_CANNED: 'EDIT_CANNED',

View file

@ -11,7 +11,7 @@ Rails.application.routes.draw do
match '/status', to: 'home#status', via: [:get]
namespace :api do
namespace :api, :defaults => { :format => 'json' } do
namespace :v1 do
resources :callbacks, only: [] do
collection do