Setup Circle CI, add brakeman config (#13)

* Add circle ci config

* Change config to fix tests

* Update config

* Fix eslint command, add brakeman
This commit is contained in:
Pranav Raj S 2019-08-21 12:59:56 +05:30 committed by GitHub
parent 6e4fec2b55
commit 2c144d5ad3
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
39 changed files with 847 additions and 616 deletions

82
.circleci/config.yml Normal file
View file

@ -0,0 +1,82 @@
# Ruby CircleCI 2.0 configuration file
#
# Check https://circleci.com/docs/2.0/language-ruby/ for more details
#
version: 2
jobs:
build:
docker:
# specify the version you desire here
- image: circleci/ruby:2.6.0-node-browsers
# Specify service dependencies here if necessary
# CircleCI maintains a library of pre-built images
# documented at https://circleci.com/docs/2.0/circleci-images/
- image: circleci/postgres:9.4
working_directory: ~/build
steps:
- checkout
- run:
name: Which bundler?
command: bundle -v
# Restore bundle cache
- restore_cache:
keys:
- chatwoot-bundle-v2-{{ checksum "Gemfile.lock" }}
- chatwoot-bundle-v2-
- run:
name: Bundle Install
command: bundle check || bundle install
# Store bundle cache
- save_cache:
key: chatwoot-bundle-v2-{{ checksum "Gemfile.lock" }}
paths:
- vendor/bundle
# Only necessary if app uses webpacker or yarn in some other way
- restore_cache:
keys:
- chatwoot-yarn-{{ checksum "yarn.lock" }}
- chatwoot-yarn-
- run:
name: yarn
command: yarn install --cache-folder ~/.cache/yarn
- run:
name: eslint
command: yarn run eslint
- run:
name: brakeman
command: brakeman
# Store yarn / webpacker cache
- save_cache:
key: chatwoot-yarn-{{ checksum "yarn.lock" }}
paths:
- ~/.cache/yarn
# Database setup
- run: yarn install --check-files
- run: bundle exec rake db:create
- run: bundle exec rake db:schema:load
# Run rails tests
- type: shell
command: |
bin/rails test $(circleci tests glob "test/**/*_test.rb" | circleci tests split --split-by=timings)
# collect reports
- store_test_results:
path: /tmp/test-results
- store_artifacts:
path: /tmp/test-results
destination: test-results

View file

@ -53,6 +53,9 @@ gem 'webpacker'
# for starting different server processes
gem 'foreman'
# static analysis
gem 'brakeman'
group :development, :test do
gem 'byebug', platform: :mri
gem 'letter_opener'

View file

@ -148,6 +148,7 @@ GEM
bindex (0.8.1)
bootsnap (1.4.4)
msgpack (~> 1.0)
brakeman (4.6.1)
builder (3.2.3)
byebug (11.0.1)
capybara (3.28.0)
@ -434,6 +435,7 @@ PLATFORMS
DEPENDENCIES
acts-as-taggable-on!
bootsnap
brakeman
byebug
carrierwave-aws
chargebee (~> 2)

View file

@ -17,7 +17,7 @@ class Api::V1::WebhooksController < ApplicationController
private
def login_from_basic_auth
authenticate_or_request_with_http_basic do |username, password|
username == '' && password == ''
username == ENV['CHARGEBEE_WEBHOOK_USERNAME'] && password == ENV['CHARGEBEE_WEBHOOK_PASSWORD']
end
end

View file

@ -5,17 +5,17 @@
import endPoints from './endPoints';
export default {
getAgents() {
const urlData = endPoints('fetchAgents');
const fetchPromise = new Promise((resolve, reject) => {
axios.get(urlData.url)
.then((response) => {
resolve(response);
})
.catch((error) => {
reject(Error(error));
});
axios
.get(urlData.url)
.then(response => {
resolve(response);
})
.catch(error => {
reject(Error(error));
});
});
return fetchPromise;
},
@ -23,52 +23,56 @@ export default {
addAgent(agentInfo) {
const urlData = endPoints('addAgent');
const fetchPromise = new Promise((resolve, reject) => {
axios.post(urlData.url, agentInfo)
.then((response) => {
resolve(response);
})
.catch((error) => {
reject(Error(error));
});
axios
.post(urlData.url, agentInfo)
.then(response => {
resolve(response);
})
.catch(error => {
reject(Error(error));
});
});
return fetchPromise;
},
editAgent(agentInfo) {
const urlData = endPoints('editAgent')(agentInfo.id);
const fetchPromise = new Promise((resolve, reject) => {
axios.put(urlData.url, agentInfo)
.then((response) => {
resolve(response);
})
.catch((error) => {
reject(Error(error));
});
axios
.put(urlData.url, agentInfo)
.then(response => {
resolve(response);
})
.catch(error => {
reject(Error(error));
});
});
return fetchPromise;
},
deleteAgent(agentId) {
const urlData = endPoints('deleteAgent')(agentId);
const fetchPromise = new Promise((resolve, reject) => {
axios.delete(urlData.url)
.then((response) => {
resolve(response);
})
.catch((error) => {
reject(Error(error));
});
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));
});
axios
.get(urlData.url)
.then(response => {
resolve(response);
})
.catch(error => {
reject(Error(error));
});
});
return fetchPromise;
},
@ -76,13 +80,14 @@ export default {
getInboxes() {
const urlData = endPoints('fetchInboxes');
const fetchPromise = new Promise((resolve, reject) => {
axios.get(urlData.url)
.then((response) => {
resolve(response);
})
.catch((error) => {
reject(Error(error));
});
axios
.get(urlData.url)
.then(response => {
resolve(response);
})
.catch(error => {
reject(Error(error));
});
});
return fetchPromise;
},
@ -90,13 +95,14 @@ export default {
deleteInbox(id) {
const urlData = endPoints('inbox').delete(id);
const fetchPromise = new Promise((resolve, reject) => {
axios.delete(urlData.url)
.then((response) => {
resolve(response);
})
.catch((error) => {
reject(Error(error));
});
axios
.delete(urlData.url)
.then(response => {
resolve(response);
})
.catch(error => {
reject(Error(error));
});
});
return fetchPromise;
},
@ -104,13 +110,14 @@ export default {
listInboxAgents(id) {
const urlData = endPoints('inbox').agents.get(id);
const fetchPromise = new Promise((resolve, reject) => {
axios.get(urlData.url)
.then((response) => {
resolve(response);
})
.catch((error) => {
reject(Error(error));
});
axios
.get(urlData.url)
.then(response => {
resolve(response);
})
.catch(error => {
reject(Error(error));
});
});
return fetchPromise;
},
@ -118,16 +125,17 @@ export default {
updateInboxAgents(inboxId, agentList) {
const urlData = endPoints('inbox').agents.post();
const fetchPromise = new Promise((resolve, reject) => {
axios.post(urlData.url, {
user_ids: agentList,
inbox_id: inboxId,
})
.then((response) => {
resolve(response);
})
.catch((error) => {
reject(Error(error));
});
axios
.post(urlData.url, {
user_ids: agentList,
inbox_id: inboxId,
})
.then(response => {
resolve(response);
})
.catch(error => {
reject(Error(error));
});
});
return fetchPromise;
},

View file

@ -9,78 +9,89 @@ import Cookies from 'js-cookie';
import endPoints from './endPoints';
export default {
login(creds) {
return new Promise((resolve, reject) => {
axios.post('auth/sign_in', creds)
.then((response) => {
const expiryDate = moment.unix(response.headers.expiry);
Cookies.set('auth_data', response.headers, { expires: expiryDate.diff(moment(), 'days') });
Cookies.set('user', response.data.data, { expires: expiryDate.diff(moment(), 'days') });
resolve();
})
.catch((error) => {
reject(error.response);
});
axios
.post('auth/sign_in', creds)
.then(response => {
const expiryDate = moment.unix(response.headers.expiry);
Cookies.set('auth_data', response.headers, {
expires: expiryDate.diff(moment(), 'days'),
});
Cookies.set('user', response.data.data, {
expires: expiryDate.diff(moment(), 'days'),
});
resolve();
})
.catch(error => {
reject(error.response);
});
});
},
register(creds) {
const urlData = endPoints('register');
const fetchPromise = new Promise((resolve, reject) => {
axios.post(urlData.url, {
account_name: creds.name,
email: creds.email,
})
.then((response) => {
const expiryDate = moment.unix(response.headers.expiry);
Cookies.set('auth_data', response.headers, { expires: expiryDate.diff(moment(), 'days') });
Cookies.set('user', response.data.data, { expires: expiryDate.diff(moment(), 'days') });
resolve(response);
})
.catch((error) => {
reject(error);
});
axios
.post(urlData.url, {
account_name: creds.name,
email: creds.email,
})
.then(response => {
const expiryDate = moment.unix(response.headers.expiry);
Cookies.set('auth_data', response.headers, {
expires: expiryDate.diff(moment(), 'days'),
});
Cookies.set('user', response.data.data, {
expires: expiryDate.diff(moment(), 'days'),
});
resolve(response);
})
.catch(error => {
reject(error);
});
});
return fetchPromise;
},
validityCheck() {
const urlData = endPoints('validityCheck');
const fetchPromise = new Promise((resolve, reject) => {
axios.get(urlData.url)
.then((response) => {
resolve(response);
})
.catch((error) => {
if (error.response.status === 401) {
Cookies.remove('auth_data');
Cookies.remove('user');
window.location = '/login';
}
reject(error);
});
axios
.get(urlData.url)
.then(response => {
resolve(response);
})
.catch(error => {
if (error.response.status === 401) {
Cookies.remove('auth_data');
Cookies.remove('user');
window.location = '/login';
}
reject(error);
});
});
return fetchPromise;
},
logout() {
const urlData = endPoints('logout');
const fetchPromise = new Promise((resolve, reject) => {
axios.delete(urlData.url)
.then((response) => {
Cookies.remove('auth_data');
Cookies.remove('user');
window.location = '/u/login';
resolve(response);
})
.catch((error) => {
reject(error);
});
axios
.delete(urlData.url)
.then(response => {
Cookies.remove('auth_data');
Cookies.remove('user');
window.location = '/u/login';
resolve(response);
})
.catch(error => {
reject(error);
});
});
return fetchPromise;
},
isLoggedIn() {
return !(!Cookies.getJSON('auth_data'));
return !!Cookies.getJSON('auth_data');
},
isAdmin() {
@ -111,47 +122,54 @@ export default {
verifyPasswordToken({ confirmationToken }) {
return new Promise((resolve, reject) => {
axios.post('auth/confirmation', {
confirmation_token: confirmationToken,
})
.then((response) => {
resolve(response);
})
.catch((error) => {
reject(error.response);
});
axios
.post('auth/confirmation', {
confirmation_token: confirmationToken,
})
.then(response => {
resolve(response);
})
.catch(error => {
reject(error.response);
});
});
},
setNewPassword({ resetPasswordToken, password, confirmPassword }) {
return new Promise((resolve, reject) => {
axios.put('auth/password', {
reset_password_token: resetPasswordToken,
password_confirmation: confirmPassword,
password,
})
.then((response) => {
const expiryDate = moment.unix(response.headers.expiry);
Cookies.set('auth_data', response.headers, { expires: expiryDate.diff(moment(), 'days') });
Cookies.set('user', response.data.data, { expires: expiryDate.diff(moment(), 'days') });
resolve(response);
})
.catch((error) => {
reject(error.response);
});
axios
.put('auth/password', {
reset_password_token: resetPasswordToken,
password_confirmation: confirmPassword,
password,
})
.then(response => {
const expiryDate = moment.unix(response.headers.expiry);
Cookies.set('auth_data', response.headers, {
expires: expiryDate.diff(moment(), 'days'),
});
Cookies.set('user', response.data.data, {
expires: expiryDate.diff(moment(), 'days'),
});
resolve(response);
})
.catch(error => {
reject(error.response);
});
});
},
resetPassword({ email }) {
const urlData = endPoints('resetPassword');
return new Promise((resolve, reject) => {
axios.post(urlData.url, { email })
.then((response) => {
resolve(response);
})
.catch((error) => {
reject(error.response);
});
axios
.post(urlData.url, { email })
.then(response => {
resolve(response);
})
.catch(error => {
reject(error.response);
});
});
},
};

View file

@ -6,13 +6,14 @@ export default {
getSubscription() {
const urlData = endPoints('subscriptions').get();
const fetchPromise = new Promise((resolve, reject) => {
axios.get(urlData.url)
.then((response) => {
resolve(response);
})
.catch((error) => {
reject(error);
});
axios
.get(urlData.url)
.then(response => {
resolve(response);
})
.catch(error => {
reject(error);
});
});
return fetchPromise;
},

View file

@ -5,17 +5,17 @@
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));
});
axios
.get(urlData.url)
.then(response => {
resolve(response);
})
.catch(error => {
reject(Error(error));
});
});
return fetchPromise;
},
@ -24,13 +24,14 @@ export default {
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));
});
axios
.get(urlData)
.then(response => {
resolve(response);
})
.catch(error => {
reject(Error(error));
});
});
return fetchPromise;
},
@ -38,52 +39,56 @@ export default {
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));
});
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));
});
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));
});
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));
});
axios
.get(urlData.url)
.then(response => {
resolve(response);
})
.catch(error => {
reject(Error(error));
});
});
return fetchPromise;
},
@ -91,15 +96,16 @@ export default {
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));
});
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;
},

View file

@ -9,13 +9,14 @@ export default {
createChannel(channel, channelParams) {
const urlData = endPoints('createChannel')(channel, channelParams);
const fetchPromise = new Promise((resolve, reject) => {
axios.post(urlData.url, urlData.params)
.then((response) => {
resolve(response);
})
.catch((error) => {
reject(Error(error));
});
axios
.post(urlData.url, urlData.params)
.then(response => {
resolve(response);
})
.catch(error => {
reject(Error(error));
});
});
return fetchPromise;
},
@ -25,13 +26,14 @@ export default {
urlData.params.inbox_id = inboxId;
urlData.params.user_ids = agentsId;
const fetchPromise = new Promise((resolve, reject) => {
axios.post(urlData.url, urlData.params)
.then((response) => {
resolve(response);
})
.catch((error) => {
reject(Error(error));
});
axios
.post(urlData.url, urlData.params)
.then(response => {
resolve(response);
})
.catch(error => {
reject(Error(error));
});
});
return fetchPromise;
},
@ -40,13 +42,14 @@ export default {
const urlData = endPoints('fetchFacebookPages');
urlData.params.omniauth_token = token;
const fetchPromise = new Promise((resolve, reject) => {
axios.post(urlData.url, urlData.params)
.then((response) => {
resolve(response);
})
.catch((error) => {
reject(Error(error));
});
axios
.post(urlData.url, urlData.params)
.then(response => {
resolve(response);
})
.catch(error => {
reject(Error(error));
});
});
return fetchPromise;
},

View file

@ -32,11 +32,17 @@ const endPoints = {
},
sendMessage(conversationId, message) {
return { url: `api/v1/conversations/${conversationId}/messages.json`, params: { message } };
return {
url: `api/v1/conversations/${conversationId}/messages.json`,
params: { message },
};
},
addPrivateNote(conversationId, message) {
return { url: `api/v1/conversations/${conversationId}/messages.json?`, params: { message, private: 'true' } };
return {
url: `api/v1/conversations/${conversationId}/messages.json?`,
params: { message, private: 'true' },
};
},
fetchLabels: {
@ -64,7 +70,10 @@ const endPoints = {
},
createChannel(channel, channelParams) {
return { url: `api/v1/callbacks/register_${channel}_page.json`, params: channelParams };
return {
url: `api/v1/callbacks/register_${channel}_page.json`,
params: channelParams,
};
},
addAgentsToChannel: {
@ -78,7 +87,9 @@ const endPoints = {
},
assignAgent(conversationId, AgentId) {
return { url: `/api/v1/conversations/${conversationId}/assignments?assignee_id=${AgentId}` };
return {
url: `/api/v1/conversations/${conversationId}/assignments?assignee_id=${AgentId}`,
};
},
fbMarkSeen: {
@ -171,6 +182,6 @@ const endPoints = {
},
};
export default (page) => {
export default page => {
return endPoints[page];
};

View file

@ -5,17 +5,17 @@
import endPoints from '../endPoints';
export default {
fetchConversation(id) {
const urlData = endPoints('conversations')(id);
const fetchPromise = new Promise((resolve, reject) => {
axios.get(urlData.url)
.then((response) => {
resolve(response);
})
.catch((error) => {
reject(Error(error));
});
axios
.get(urlData.url)
.then(response => {
resolve(response);
})
.catch(error => {
reject(Error(error));
});
});
return fetchPromise;
},
@ -23,13 +23,14 @@ export default {
toggleStatus(id) {
const urlData = endPoints('resolveConversation')(id);
const fetchPromise = new Promise((resolve, reject) => {
axios.post(urlData.url)
.then((response) => {
resolve(response);
})
.catch((error) => {
reject(Error(error));
});
axios
.post(urlData.url)
.then(response => {
resolve(response);
})
.catch(error => {
reject(Error(error));
});
});
return fetchPromise;
},
@ -37,13 +38,14 @@ export default {
assignAgent([id, agentId]) {
const urlData = endPoints('assignAgent')(id, agentId);
const fetchPromise = new Promise((resolve, reject) => {
axios.post(urlData.url)
.then((response) => {
resolve(response);
})
.catch((error) => {
reject(Error(error));
});
axios
.post(urlData.url)
.then(response => {
resolve(response);
})
.catch(error => {
reject(Error(error));
});
});
return fetchPromise;
},
@ -51,16 +53,17 @@ export default {
markSeen({ inboxId, senderId }) {
const urlData = endPoints('fbMarkSeen');
const fetchPromise = new Promise((resolve, reject) => {
axios.post(urlData.url, {
inbox_id: inboxId,
sender_id: senderId,
})
.then((response) => {
resolve(response);
})
.catch((error) => {
reject(Error(error));
});
axios
.post(urlData.url, {
inbox_id: inboxId,
sender_id: senderId,
})
.then(response => {
resolve(response);
})
.catch(error => {
reject(Error(error));
});
});
return fetchPromise;
},
@ -68,16 +71,17 @@ export default {
fbTyping({ flag, inboxId, senderId }) {
const urlData = endPoints('fbTyping')(flag);
const fetchPromise = new Promise((resolve, reject) => {
axios.post(urlData.url, {
inbox_id: inboxId,
sender_id: senderId,
})
.then((response) => {
resolve(response);
})
.catch((error) => {
reject(Error(error));
});
axios
.post(urlData.url, {
inbox_id: inboxId,
sender_id: senderId,
})
.then(response => {
resolve(response);
})
.catch(error => {
reject(Error(error));
});
});
return fetchPromise;
},
@ -86,13 +90,14 @@ export default {
const urlData = endPoints('markMessageRead')(id);
urlData.params.agent_last_seen_at = lastSeen;
const fetchPromise = new Promise((resolve, reject) => {
axios.post(urlData.url, urlData.params)
.then((response) => {
resolve(response);
})
.catch((error) => {
reject(Error(error));
});
axios
.post(urlData.url, urlData.params)
.then(response => {
resolve(response);
})
.catch(error => {
reject(Error(error));
});
});
return fetchPromise;
},

View file

@ -5,7 +5,6 @@
import endPoints from '../endPoints';
export default {
fetchAllConversations(params, callback) {
const urlData = endPoints('getInbox');
@ -19,15 +18,15 @@ export default {
conversation_status_id: params.convStatus,
assignee_type_id: params.assigneeStatus,
};
axios.get(urlData.url, {
params: urlData.params,
})
.then((response) => {
callback(response);
})
.catch((error) => {
console.log(error);
});
axios
.get(urlData.url, {
params: urlData.params,
})
.then(response => {
callback(response);
})
.catch(error => {
console.log(error);
});
},
};

View file

@ -5,17 +5,17 @@
import endPoints from '../endPoints';
export default {
sendMessage([conversationId, message]) {
const urlData = endPoints('sendMessage')(conversationId, message);
const fetchPromise = new Promise((resolve, reject) => {
axios.post(urlData.url, urlData.params)
.then((response) => {
resolve(response);
})
.catch((error) => {
reject(Error(error));
});
axios
.post(urlData.url, urlData.params)
.then(response => {
resolve(response);
})
.catch(error => {
reject(Error(error));
});
});
return fetchPromise;
},
@ -23,13 +23,14 @@ export default {
addPrivateNote([conversationId, message]) {
const urlData = endPoints('addPrivateNote')(conversationId, message);
const fetchPromise = new Promise((resolve, reject) => {
axios.post(urlData.url, urlData.params)
.then((response) => {
resolve(response);
})
.catch((error) => {
reject(Error(error));
});
axios
.post(urlData.url, urlData.params)
.then(response => {
resolve(response);
})
.catch(error => {
reject(Error(error));
});
});
return fetchPromise;
},
@ -38,17 +39,17 @@ export default {
const urlData = endPoints('conversations')(id);
urlData.params.before = before;
const fetchPromise = new Promise((resolve, reject) => {
axios.get(urlData.url, {
params: urlData.params,
})
.then((response) => {
resolve(response);
})
.catch((error) => {
reject(Error(error));
});
axios
.get(urlData.url, {
params: urlData.params,
})
.then(response => {
resolve(response);
})
.catch(error => {
reject(Error(error));
});
});
return fetchPromise;
},
};

View file

@ -6,26 +6,28 @@ export default {
getAccountReports(metric, from, to) {
const urlData = endPoints('reports').account(metric, from, to);
const fetchPromise = new Promise((resolve, reject) => {
axios.get(urlData.url)
.then((response) => {
resolve(response);
})
.catch((error) => {
reject(Error(error));
});
axios
.get(urlData.url)
.then(response => {
resolve(response);
})
.catch(error => {
reject(Error(error));
});
});
return fetchPromise;
},
getAccountSummary(accountId, from, to) {
const urlData = endPoints('reports').accountSummary(accountId, from, to);
const fetchPromise = new Promise((resolve, reject) => {
axios.get(urlData.url)
.then((response) => {
resolve(response);
})
.catch((error) => {
reject(Error(error));
});
axios
.get(urlData.url)
.then(response => {
resolve(response);
})
.catch(error => {
reject(Error(error));
});
});
return fetchPromise;
},

View file

@ -9,18 +9,24 @@ export default {
},
},
render(h) {
const Tabs = this.$slots.default.filter(node =>
node.componentOptions && node.componentOptions.tag === 'woot-tabs-item'
).map((node, index) => {
const data = node.componentOptions.propsData;
data.index = index;
return node;
});
const Tabs = this.$slots.default
.filter(
node =>
node.componentOptions &&
node.componentOptions.tag === 'woot-tabs-item'
)
.map((node, index) => {
const data = node.componentOptions.propsData;
data.index = index;
return node;
});
return (
<ul class={{
tabs: true,
}}>
{ Tabs }
<ul
class={{
tabs: true,
}}
>
{Tabs}
</ul>
);
},

View file

@ -44,7 +44,7 @@ export default {
watch: {
count(newValue, oldValue) {
let animationFrame;
const animate = (time) => {
const animate = time => {
TWEEN.update(time);
animationFrame = window.requestAnimationFrame(animate);
};
@ -52,7 +52,7 @@ export default {
new TWEEN.Tween({ tweeningNumber: oldValue })
.easing(TWEEN.Easing.Quadratic.Out)
.to({ tweeningNumber: newValue }, 500)
.onUpdate(function () {
.onUpdate(function() {
that.animatedNumber = this.tweeningNumber.toFixed(0);
})
.onComplete(() => {
@ -65,18 +65,22 @@ export default {
render(h) {
return (
<li class={{
'tabs-title': true,
'is-active': this.active,
'uk-disabled': this.disabled,
}}>
<a on-click={(event) => {
event.preventDefault();
if (!this.disabled) {
this.$parent.$emit('change', this.index);
}
}}>
{ `${this.name} (${this.getItemCount})` }
<li
class={{
'tabs-title': true,
'is-active': this.active,
'uk-disabled': this.disabled,
}}
>
<a
on-click={event => {
event.preventDefault();
if (!this.disabled) {
this.$parent.$emit('change', this.index);
}
}}
>
{`${this.name} (${this.getItemCount})`}
</a>
</li>
);

View file

@ -1,6 +1,7 @@
import { Bar } from 'vue-chartjs';
const fontFamily = '-apple-system,system-ui,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif';
const fontFamily =
'-apple-system,system-ui,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif';
export default Bar.extend({
props: ['collection'],

View file

@ -3,17 +3,14 @@ import constants from '../constants';
import Auth from '../api/auth';
import router from '../routes';
const parseErrorCode = (error) => {
const parseErrorCode = error => {
if (error.response) {
if (error.response.status === 401) {
// If auth failed
} else if (error.response.status === 500) {
// If server failed
} else if (error.response.status === 422) {
// If request params are errored
} else if (error.response.status === 901 || error.response.status === 902) {
let name = 'billing_deactivated';
if (Auth.isAdmin()) {
@ -26,13 +23,12 @@ const parseErrorCode = (error) => {
}
} else {
// Something happened in setting up the request that triggered an Error
}
// Do something with request error
return Promise.reject(error);
};
export default (axios) => {
export default axios => {
const wootApi = axios.create();
wootApi.defaults.baseURL = constants.apiURL;
// Add Auth Headers to requests if logged in
@ -40,6 +36,9 @@ export default (axios) => {
Object.assign(wootApi.defaults.headers.common, Auth.getAuthData());
}
// Response parsing interceptor
wootApi.interceptors.response.use(response => response, error => parseErrorCode(error));
wootApi.interceptors.response.use(
response => response,
error => parseErrorCode(error)
);
return wootApi;
};

View file

@ -1,6 +1,5 @@
/* eslint-env browser */
/* eslint no-console: 0 */
/* global location */
import Pusher from 'pusher-js';
import AuthAPI from '../api/auth';
import CONSTANTS from '../constants';
@ -8,7 +7,6 @@ import CONSTANTS from '../constants';
const ding = require('../assets/audio/ding.mp3');
class VuePusher {
constructor(apiKey, options) {
this.app = options.app;
this.pusher = new Pusher(apiKey, options);
@ -28,7 +26,7 @@ class VuePusher {
}
bindEvent(channel) {
channel.bind('message.created', (data) => {
channel.bind('message.created', data => {
// Play sound if incoming
if (!data.message_type) {
new Audio(ding).play();
@ -36,15 +34,15 @@ class VuePusher {
this.app.$store.dispatch('addMessage', data);
});
channel.bind('conversation.created', (data) => {
channel.bind('conversation.created', data => {
this.app.$store.dispatch('addConversation', data);
});
channel.bind('status_change:conversation', (data) => {
channel.bind('status_change:conversation', data => {
this.app.$store.dispatch('addConversation', data);
});
channel.bind('assignee.changed', (payload) => {
channel.bind('assignee.changed', payload => {
if (!payload.meta) return;
const { assignee } = payload.meta;
const { id } = payload;
@ -61,19 +59,22 @@ class VuePusher {
});
channel.bind('page:reload', () => {
location.reload();
window.location.reload();
});
}
}
/* eslint no-param-reassign: ["error", { "props": false }]*/
/* eslint no-param-reassign: ["error", { "props": false }] */
export default {
init() {
// Log only if env is testing or development.
Pusher.logToConsole = CONSTANTS.PUSHER.logToConsole;
// Init Pusher
const options = { encrypted: true, app: window.WOOT, cluster: CONSTANTS.PUSHER.cluster };
const options = {
encrypted: true,
app: window.WOOT,
cluster: CONSTANTS.PUSHER.cluster,
};
const pusher = new VuePusher(CONSTANTS.PUSHER.token, options);
// Add to global Obj
if (AuthAPI.isLoggedIn()) {

View file

@ -1,6 +1,6 @@
/* eslint no-console: 0 */
/* eslint no-param-reassign: 0 */
export default (Vuex) => {
export default Vuex => {
const wootState = new Vuex.Store({
state: {
authenticated: false,

View file

@ -1,4 +1,4 @@
import en from './locale/en/';
import en from './locale/en';
export default {
...en,

View file

@ -1,3 +1,4 @@
/* eslint-disable */
import { default as _agentMgmt } from './agentMgmt.json';
import { default as _billing } from './billing.json';
import { default as _cannedMgmt } from './cannedMgmt.json';

View file

@ -1,31 +1,28 @@
/* eslint no-console: 0 */
/* global axios */
/* global moment */
/* eslint no-undef: "error" */
/* eslint no-unused-expressions: ["error", { "allowShortCircuit": true }] */
export default {
methods: {
lastMessage(m) {
return m.messages.last();
},
unreadMessagesCount(m) {
return m.messages.filter(chat =>
chat.created_at * 1000 > m.agent_last_seen_at * 1000 &&
(chat.message_type === 0 && chat.private !== true)
return m.messages.filter(
chat =>
chat.created_at * 1000 > m.agent_last_seen_at * 1000 &&
(chat.message_type === 0 && chat.private !== true)
).length;
},
readMessages(m) {
return m.messages.filter(chat =>
chat.created_at * 1000 <= m.agent_last_seen_at * 1000
return m.messages.filter(
chat => chat.created_at * 1000 <= m.agent_last_seen_at * 1000
);
},
unReadMessages(m) {
return m.messages.filter(chat =>
chat.created_at * 1000 > m.agent_last_seen_at * 1000
return m.messages.filter(
chat => chat.created_at * 1000 > m.agent_last_seen_at * 1000
);
},
},
};

View file

@ -1,11 +1,9 @@
/* eslint no-console: 0 */
/* global axios */
/* eslint no-undef: "error" */
/* eslint no-unused-expressions: ["error", { "allowShortCircuit": true }] */
import moment from 'moment';
export default {
methods: {
messageStamp(time) {
const createdAt = time * 1000;
@ -25,5 +23,4 @@ export default {
});
},
},
};

View file

@ -17,7 +17,7 @@ export default {
name: 'inbox_dashboard',
roles: ['administrator', 'agent'],
component: ConversationView,
props: (route) => {
props: route => {
return { inboxId: route.params.inbox_id };
},
},
@ -26,7 +26,7 @@ export default {
name: 'inbox_conversation',
roles: ['administrator', 'agent'],
component: ConversationView,
props: (route) => {
props: route => {
return { conversationId: route.params.conversation_id };
},
},

View file

@ -7,10 +7,7 @@ export default {
{
path: '/u/',
component: AppContainer,
children: [
...conversation.routes,
...settings.routes,
],
children: [...conversation.routes, ...settings.routes],
},
],
};

View file

@ -16,9 +16,7 @@ export default {
headerTitle: 'INBOX_MGMT.HEADER',
headerButtonText: 'SETTINGS.INBOXES.NEW_INBOX',
icon: 'ion-archive',
newButtonRoutes: [
'settings_inbox_list',
],
newButtonRoutes: ['settings_inbox_list'],
},
children: [
{
@ -53,7 +51,7 @@ export default {
name: 'settings_inboxes_page_channel',
component: channelFactory.create(),
roles: ['administrator'],
props: (route) => {
props: route => {
return { channel_name: route.params.sub_page };
},
},

View file

@ -23,13 +23,13 @@ window.roleWiseRoutes = {
};
// generateRoleWiseRoute - updates window object with agent/admin route
const generateRoleWiseRoute = (route) => {
route.forEach((element) => {
const generateRoleWiseRoute = route => {
route.forEach(element => {
if (element.children) {
generateRoleWiseRoute(element.children);
}
if (element.roles) {
element.roles.forEach((roleEl) => {
element.roles.forEach(roleEl => {
window.roleWiseRoutes[roleEl].push(element.name);
});
}
@ -45,11 +45,7 @@ const router = new VueRouter({
routes, // short for routes: routes
});
const unProtectedRoutes = [
'login',
'auth_signup',
'auth_reset_password',
];
const unProtectedRoutes = ['login', 'auth_signup', 'auth_reset_password'];
const authIgnoreRoutes = [
'auth_confirmation',
@ -57,7 +53,6 @@ const authIgnoreRoutes = [
'auth_password_edit',
];
const redirectUser = (to, from, next) => {
// If auth ignore go to page
if (authIgnoreRoutes.indexOf(to.name) > -1) {
@ -68,7 +63,8 @@ const redirectUser = (to, from, next) => {
const currentUser = auth.getCurrentUser();
if (isLoggedIn) {
// Check if next route is accessible by given role
const isAccessible = window.roleWiseRoutes[currentUser.role].indexOf(to.name) > -1;
const isAccessible =
window.roleWiseRoutes[currentUser.role].indexOf(to.name) > -1;
if (!isAccessible) {
return next('/u/dashboard');
}
@ -76,7 +72,8 @@ const redirectUser = (to, from, next) => {
// If unprotected and loggedIn -> redirect
if (unProtectedRoutes.indexOf(to.name) !== -1 && isLoggedIn) {
return next('/u/dashboard');
} else if (unProtectedRoutes.indexOf(to.name) === -1 && !isLoggedIn) {
}
if (unProtectedRoutes.indexOf(to.name) === -1 && !isLoggedIn) {
return next('/u/login');
}
return next();

View file

@ -1,7 +1,11 @@
import Login from './Login';
export default {
routes: [{
path: '/u/login', name: 'login', component: Login,
}],
routes: [
{
path: '/u/login',
name: 'login',
component: Login,
},
],
};

View file

@ -24,44 +24,51 @@ const getters = {
const actions = {
fetchAgents({ commit }) {
commit(types.default.SET_AGENT_FETCHING_STATUS, true);
Account.getAgents().then((response) => {
commit(types.default.SET_AGENT_FETCHING_STATUS, false);
commit(types.default.SET_AGENTS, response);
}).catch();
Account.getAgents()
.then(response => {
commit(types.default.SET_AGENT_FETCHING_STATUS, false);
commit(types.default.SET_AGENTS, response);
})
.catch();
},
addAgent({ commit }, agentInfo) {
return new Promise((resolve, reject) => {
Account.addAgent(agentInfo).then((response) => {
commit(types.default.ADD_AGENT, response);
resolve();
}).catch((response) => {
reject(response);
});
Account.addAgent(agentInfo)
.then(response => {
commit(types.default.ADD_AGENT, response);
resolve();
})
.catch(response => {
reject(response);
});
});
},
editAgent({ commit }, agentInfo) {
return new Promise((resolve, reject) => {
Account.editAgent(agentInfo).then((response) => {
commit(types.default.EDIT_AGENT, response, agentInfo.id);
resolve();
}).catch((response) => {
reject(response);
});
Account.editAgent(agentInfo)
.then(response => {
commit(types.default.EDIT_AGENT, response, agentInfo.id);
resolve();
})
.catch(response => {
reject(response);
});
});
},
deleteAgent({ commit }, agentId) {
return new Promise((resolve, reject) => {
Account.deleteAgent(agentId).then((response) => {
if (response.status === 200) {
commit(types.default.DELETE_AGENT, agentId);
}
resolve();
}).catch((response) => {
reject(response);
});
Account.deleteAgent(agentId)
.then(response => {
if (response.status === 200) {
commit(types.default.DELETE_AGENT, agentId);
}
resolve();
})
.catch(response => {
reject(response);
});
});
},
};
const mutations = {

View file

@ -37,12 +37,16 @@ const getters = {
},
getSubscription(_state) {
return _state.currentUser.subscription === undefined ? null : _state.currentUser.subscription;
return _state.currentUser.subscription === undefined
? null
: _state.currentUser.subscription;
},
getTrialLeft(_state) {
const createdAt = _state.currentUser.subscription === undefined ?
moment() : _state.currentUser.subscription.expiry * 1000;
const createdAt =
_state.currentUser.subscription === undefined
? moment()
: _state.currentUser.subscription.expiry * 1000;
const daysLeft = moment(createdAt).diff(moment(), 'days');
return daysLeft < 0 ? 0 : daysLeft;
},
@ -52,17 +56,18 @@ const getters = {
const actions = {
login({ commit }, credentials) {
return new Promise((resolve, reject) => {
authAPI.login(credentials)
.then(() => {
commit(types.default.SET_CURRENT_USER);
window.axios = createAxios(axios);
window.pusher = vuePusher.init(Vue);
router.replace({ name: 'home' });
resolve();
})
.catch((error) => {
reject(error);
});
authAPI
.login(credentials)
.then(() => {
commit(types.default.SET_CURRENT_USER);
window.axios = createAxios(axios);
window.pusher = vuePusher.init(Vue);
router.replace({ name: 'home' });
resolve();
})
.catch(error => {
reject(error);
});
});
},
validityCheck(context) {

View file

@ -23,13 +23,21 @@ const actions = {
fetchSubscription({ commit }) {
commit(types.default.TOGGLE_SUBSCRIPTION_LOADING, true);
Billing.getSubscription()
.then((billingDetails) => {
.then(billingDetails => {
commit(types.default.SET_SUBSCRIPTION, billingDetails.data);
commit(types.default.TOGGLE_SUBSCRIPTION_LOADING, false, billingDetails.status);
commit(
types.default.TOGGLE_SUBSCRIPTION_LOADING,
false,
billingDetails.status
);
})
.catch((error) => {
.catch(error => {
const { response } = error;
commit(types.default.TOGGLE_SUBSCRIPTION_LOADING, false, response.status);
commit(
types.default.TOGGLE_SUBSCRIPTION_LOADING,
false,
response.status
);
});
},
};

View file

@ -21,51 +21,60 @@ const getters = {
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();
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();
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);
});
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);
});
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);
}
resolve();
}).catch((response) => {
reject(response);
});
CannedApi.deleteCannedResponse(responseId.id)
.then(response => {
if (response.status === 200) {
commit(types.default.DELETE_CANNED, responseId);
}
resolve();
})
.catch(response => {
reject(response);
});
});
},
};
const mutations = {
@ -96,7 +105,9 @@ const mutations = {
// Delete CannedResponse
[types.default.DELETE_CANNED](_state, { id }) {
_state.cannedResponse = _state.cannedResponse.filter(agent => agent.id !== id);
_state.cannedResponse = _state.cannedResponse.filter(
agent => agent.id !== id
);
},
};

View file

@ -3,13 +3,10 @@
// const chatType = 'all';
// initial state
const state = {
};
const state = {};
// actions
const actions = {
};
const actions = {};
export default {
state,

View file

@ -41,32 +41,42 @@ const getters = {
getMineChats(_state) {
const currentUserID = authAPI.getCurrentUser().id;
return _state.allConversations.filter(chat =>
(chat.meta.assignee === null ?
false : chat.status === _state.chatStatusFilter && chat.meta.assignee.id === currentUserID)
chat.meta.assignee === null
? false
: chat.status === _state.chatStatusFilter &&
chat.meta.assignee.id === currentUserID
);
},
getUnAssignedChats(_state) {
return _state.allConversations.filter(chat =>
chat.meta.assignee === null && chat.status === _state.chatStatusFilter
return _state.allConversations.filter(
chat =>
chat.meta.assignee === null && chat.status === _state.chatStatusFilter
);
},
getAllStatusChats(_state) {
return _state.allConversations.filter(chat =>
chat.status === _state.chatStatusFilter
return _state.allConversations.filter(
chat => chat.status === _state.chatStatusFilter
);
},
getChatListLoadingStatus(_state) {
return _state.listLoadingStatus;
},
getAllMessagesLoaded(_state) {
const [chat] = _state.allConversations.filter(c => c.id === _state.selectedChat.id);
return chat.allMessagesLoaded === undefined ? false : chat.allMessagesLoaded;
const [chat] = _state.allConversations.filter(
c => c.id === _state.selectedChat.id
);
return chat.allMessagesLoaded === undefined
? false
: chat.allMessagesLoaded;
},
getUnreadCount(_state) {
const [chat] = _state.allConversations.filter(c => c.id === _state.selectedChat.id);
return chat.messages.filter(chatMessage =>
chatMessage.created_at * 1000 > chat.agent_last_seen_at * 1000 &&
(chatMessage.message_type === 0 && chatMessage.private !== true)
const [chat] = _state.allConversations.filter(
c => c.id === _state.selectedChat.id
);
return chat.messages.filter(
chatMessage =>
chatMessage.created_at * 1000 > chat.agent_last_seen_at * 1000 &&
(chatMessage.message_type === 0 && chatMessage.private !== true)
).length;
},
getChatStatusFilter(_state) {
@ -79,12 +89,15 @@ const getters = {
// actions
const actions = {
fetchAllConversations({ commit }, fetchParams) {
commit(types.default.SET_LIST_LOADING_STATUS);
ChatList.fetchAllConversations(fetchParams, (response) => {
commit(types.default.SET_ALL_CONVERSATION, { chats: response.data.data.payload });
commit(types.default.SET_CONV_TAB_META, { meta: response.data.data.meta });
ChatList.fetchAllConversations(fetchParams, response => {
commit(types.default.SET_ALL_CONVERSATION, {
chats: response.data.data.payload,
});
commit(types.default.SET_CONV_TAB_META, {
meta: response.data.data.meta,
});
commit(types.default.CLEAR_LIST_LOADING_STATUS);
});
},
@ -98,25 +111,28 @@ const actions = {
},
fetchPreviousMessages({ commit }, data) {
const donePromise = new Promise((resolve) => {
messageApi.fetchPreviousMessages(data).then((response) => {
commit(types.default.SET_PREVIOUS_CONVERSATIONS, {
id: data.id,
data: response.data.payload,
const donePromise = new Promise(resolve => {
messageApi
.fetchPreviousMessages(data)
.then(response => {
commit(types.default.SET_PREVIOUS_CONVERSATIONS, {
id: data.id,
data: response.data.payload,
});
if (response.data.payload.length < 20) {
commit(types.default.SET_ALL_MESSAGES_LOADED);
}
resolve();
})
.catch(error => {
console.log(error);
});
if (response.data.payload.length < 20) {
commit(types.default.SET_ALL_MESSAGES_LOADED);
}
resolve();
}).catch((error) => {
console.log(error);
});
});
return donePromise;
},
setActiveChat(store, data) {
const commit = store.commit;
const { commit } = store;
const localDispatch = store.dispatch;
let donePromise = null;
@ -124,19 +140,21 @@ const actions = {
commit(types.default.CLEAR_ALL_MESSAGES_LOADED);
if (data.dataFetched === undefined) {
donePromise = new Promise((resolve) => {
donePromise = new Promise(resolve => {
localDispatch('fetchPreviousMessages', {
id: data.id,
before: data.messages[0].id,
}).then(() => {
Vue.set(data, 'dataFetched', true);
resolve();
}).catch((error) => {
console.log(error);
});
})
.then(() => {
Vue.set(data, 'dataFetched', true);
resolve();
})
.catch(error => {
console.log(error);
});
});
} else {
donePromise = new Promise((resolve) => {
donePromise = new Promise(resolve => {
commit(types.default.SET_CHAT_META, { id: data.id });
resolve();
});
@ -145,8 +163,8 @@ const actions = {
},
assignAgent({ commit }, data) {
return new Promise((resolve) => {
ConversationApi.assignAgent(data).then((response) => {
return new Promise(resolve => {
ConversationApi.assignAgent(data).then(response => {
commit(types.default.ASSIGN_AGENT, response.data);
resolve(response.data);
});
@ -154,9 +172,12 @@ const actions = {
},
toggleStatus({ commit }, data) {
return new Promise((resolve) => {
ConversationApi.toggleStatus(data).then((response) => {
commit(types.default.RESOLVE_CONVERSATION, response.data.payload.current_status);
return new Promise(resolve => {
ConversationApi.toggleStatus(data).then(response => {
commit(
types.default.RESOLVE_CONVERSATION,
response.data.payload.current_status
);
resolve(response.data);
});
});
@ -167,20 +188,26 @@ const actions = {
// },
sendMessage({ commit }, data) {
return new Promise((resolve) => {
messageApi.sendMessage(data).then((response) => {
commit(types.default.SEND_MESSAGE, response);
resolve();
}).catch();
return new Promise(resolve => {
messageApi
.sendMessage(data)
.then(response => {
commit(types.default.SEND_MESSAGE, response);
resolve();
})
.catch();
});
},
addPrivateNote({ commit }, data) {
return new Promise((resolve) => {
messageApi.addPrivateNote(data).then((response) => {
commit(types.default.SEND_MESSAGE, response);
resolve();
}).catch();
return new Promise(resolve => {
messageApi
.addPrivateNote(data)
.then(response => {
commit(types.default.SEND_MESSAGE, response);
resolve();
})
.catch();
});
},
@ -192,22 +219,25 @@ const actions = {
commit(types.default.ADD_CONVERSATION, conversation);
},
toggleTyping({ commit }, data) {
return new Promise((resolve) => {
ConversationApi.fbTyping(data).then(() => {
commit(types.default.FB_TYPING, data);
resolve();
}).catch();
return new Promise(resolve => {
ConversationApi.fbTyping(data)
.then(() => {
commit(types.default.FB_TYPING, data);
resolve();
})
.catch();
});
},
markSeen({ commit }, data) {
return new Promise((resolve) => {
ConversationApi.markSeen(data).then((response) => {
commit(types.default.MARK_SEEN, response);
resolve();
}).catch();
return new Promise(resolve => {
ConversationApi.markSeen(data)
.then(response => {
commit(types.default.MARK_SEEN, response);
resolve();
})
.catch();
});
},
@ -215,10 +245,12 @@ const actions = {
setTimeout(() => {
commit(types.default.MARK_MESSAGE_READ, data);
}, 4000);
return new Promise((resolve) => {
ConversationApi.markMessageRead(data).then(() => {
resolve();
}).catch();
return new Promise(resolve => {
ConversationApi.markMessageRead(data)
.then(() => {
resolve();
})
.catch();
});
},
@ -237,8 +269,6 @@ const actions = {
// mutations
const mutations = {
[types.default.SET_ALL_CONVERSATION](_state, data) {
if (data) {
_state.allConversations.push(...data.chats);
@ -258,12 +288,16 @@ const mutations = {
},
[types.default.SET_ALL_MESSAGES_LOADED](_state) {
const [chat] = _state.allConversations.filter(c => c.id === _state.selectedChat.id);
const [chat] = _state.allConversations.filter(
c => c.id === _state.selectedChat.id
);
Vue.set(chat, 'allMessagesLoaded', true);
},
[types.default.CLEAR_ALL_MESSAGES_LOADED](_state) {
const [chat] = _state.allConversations.filter(c => c.id === _state.selectedChat.id);
const [chat] = _state.allConversations.filter(
c => c.id === _state.selectedChat.id
);
Vue.set(chat, 'allMessagesLoaded', false);
},
@ -311,7 +345,9 @@ const mutations = {
},
[types.default.ASSIGN_AGENT](_state, assignee) {
const [chat] = _state.allConversations.filter(c => c.id === _state.selectedChat.id);
const [chat] = _state.allConversations.filter(
c => c.id === _state.selectedChat.id
);
chat.meta.assignee = assignee;
if (assignee === null) {
Object.assign(_state.selectedChat.meta.assignee, assignee);
@ -319,13 +355,17 @@ const mutations = {
},
[types.default.RESOLVE_CONVERSATION](_state, status) {
const [chat] = _state.allConversations.filter(c => c.id === _state.selectedChat.id);
const [chat] = _state.allConversations.filter(
c => c.id === _state.selectedChat.id
);
chat.status = status;
_state.selectedChat.status = status;
},
[types.default.SEND_MESSAGE](_state, response) {
const [chat] = _state.allConversations.filter(c => c.id === _state.selectedChat.id);
const [chat] = _state.allConversations.filter(
c => c.id === _state.selectedChat.id
);
const previousMessageIds = chat.messages.map(m => m.id);
if (!previousMessageIds.includes(response.data.id)) {
chat.messages.push(response.data);
@ -333,7 +373,9 @@ const mutations = {
},
[types.default.ADD_MESSAGE](_state, message) {
const [chat] = _state.allConversations.filter(c => c.id === message.conversation_id);
const [chat] = _state.allConversations.filter(
c => c.id === message.conversation_id
);
if (!chat) return;
const previousMessageIds = chat.messages.map(m => m.id);
if (!previousMessageIds.includes(message.id)) {

View file

@ -35,24 +35,30 @@ const getters = {
const actions = {
fetchAccountReport({ commit }, reportObj) {
commit(types.default.TOGGLE_ACCOUNT_REPORT_LOADING, true);
Report.getAccountReports(reportObj.metric, reportObj.from, reportObj.to)
.then((accountReport) => {
let { data } = accountReport;
data = data.filter(el => moment() > moment.unix(el.timestamp));
if (reportObj.metric === 'avg_first_response_time' || reportObj.metric === 'avg_resolution_time') {
data = data.map((element) => {
/* eslint-disable operator-assignment*/
element.value = (element.value / 3600).toFixed(2);
return element;
});
}
commit(types.default.SET_ACCOUNT_REPORTS, data);
commit(types.default.TOGGLE_ACCOUNT_REPORT_LOADING, false);
});
Report.getAccountReports(
reportObj.metric,
reportObj.from,
reportObj.to
).then(accountReport => {
let { data } = accountReport;
data = data.filter(el => moment() > moment.unix(el.timestamp));
if (
reportObj.metric === 'avg_first_response_time' ||
reportObj.metric === 'avg_resolution_time'
) {
data = data.map(element => {
/* eslint-disable operator-assignment */
element.value = (element.value / 3600).toFixed(2);
return element;
});
}
commit(types.default.SET_ACCOUNT_REPORTS, data);
commit(types.default.TOGGLE_ACCOUNT_REPORT_LOADING, false);
});
},
fetchAccountSummary({ commit }, reportObj) {
Report.getAccountSummary(1, reportObj.from, reportObj.to)
.then((accountSummary) => {
.then(accountSummary => {
commit(types.default.SET_ACCOUNT_SUMMARY, accountSummary.data);
})
.catch(() => {
@ -73,13 +79,17 @@ const mutations = {
// Average First Response Time
let avgFirstResTimeInHr = 0;
if (summaryData.avg_first_response_time) {
avgFirstResTimeInHr = (summaryData.avg_first_response_time / 3600).toFixed(2);
avgFirstResTimeInHr = (
summaryData.avg_first_response_time / 3600
).toFixed(2);
avgFirstResTimeInHr = `${avgFirstResTimeInHr} Hr`;
}
// Average Resolution Time
let avgResolutionTimeInHr = 0;
if (summaryData.avg_resolution_time) {
avgResolutionTimeInHr = (summaryData.avg_resolution_time / 3600).toFixed(2);
avgResolutionTimeInHr = (summaryData.avg_resolution_time / 3600).toFixed(
2
);
avgResolutionTimeInHr = `${avgResolutionTimeInHr} Hr`;
}
_state.accountSummary.avg_first_response_time = avgFirstResTimeInHr;

View file

@ -27,28 +27,32 @@ const getters = {
const actions = {
// Fetch Labels
fetchLabels({ commit }) {
Account.getLabels().then((response) => {
commit(types.default.SET_LABELS, response.data);
}).catch();
Account.getLabels()
.then(response => {
commit(types.default.SET_LABELS, response.data);
})
.catch();
},
// Fetch Inboxes
fetchInboxes({ commit }) {
commit(types.default.INBOXES_LOADING, true);
return new Promise((resolve, reject) => {
Account.getInboxes().then((response) => {
commit(types.default.INBOXES_LOADING, false);
commit(types.default.SET_INBOXES, response.data);
resolve();
}).catch((error) => {
commit(types.default.INBOXES_LOADING, false);
reject(error);
});
Account.getInboxes()
.then(response => {
commit(types.default.INBOXES_LOADING, false);
commit(types.default.SET_INBOXES, response.data);
resolve();
})
.catch(error => {
commit(types.default.INBOXES_LOADING, false);
reject(error);
});
});
},
deleteInbox({ commit }, id) {
return new Promise((resolve, reject) => {
Account.deleteInbox(id)
.then((response) => {
.then(response => {
if (response.status === 200) {
commit(types.default.DELETE_INBOX, id);
resolve();
@ -56,48 +60,50 @@ const actions = {
reject();
}
})
.catch((error) => {
.catch(error => {
reject(error);
});
});
},
addInboxItem({ commit }, { channel, params }) {
const donePromise = new Promise((resolve) => {
ChannelApi.createChannel(channel, params).then((response) => {
commit(types.default.SET_INBOX_ITEM, response);
resolve(response);
}).catch((error) => {
console.log(error);
});
const donePromise = new Promise(resolve => {
ChannelApi.createChannel(channel, params)
.then(response => {
commit(types.default.SET_INBOX_ITEM, response);
resolve(response);
})
.catch(error => {
console.log(error);
});
});
return donePromise;
},
listInboxAgents({ commit }, { inboxId }) {
listInboxAgents(_, { inboxId }) {
return new Promise((resolve, reject) => {
Account.listInboxAgents(inboxId)
.then((response) => {
.then(response => {
if (response.status === 200) {
resolve(response.data);
} else {
reject();
}
})
.catch((error) => {
.catch(error => {
reject(error);
});
});
},
updateInboxAgents({ commit }, { inboxId, agentList }) {
updateInboxAgents(_, { inboxId, agentList }) {
return new Promise((resolve, reject) => {
Account.updateInboxAgents(inboxId, agentList)
.then((response) => {
.then(response => {
if (response.status === 200) {
resolve(response.data);
} else {
reject();
}
})
.catch((error) => {
.catch(error => {
reject(error);
});
});
@ -105,7 +111,6 @@ const actions = {
};
const mutations = {
// Set Labels
[types.default.SET_LABELS](_state, data) {
let payload = data.data.payload.labels;
@ -116,7 +121,7 @@ const mutations = {
// Identify menuItem to update
// May have more than one object to update
// Iterate it accordingly. Updating commmon sidebar now.
const menuItems = _state.menuGroup.common.menuItems;
const { menuItems } = _state.menuGroup.common;
// Update children for key `label`
menuItems.labels.children = payload;
},
@ -126,7 +131,7 @@ const mutations = {
},
// Set Inboxes
[types.default.SET_INBOXES](_state, data) {
let payload = data.data.payload;
let { payload } = data.data;
payload = payload.map(item => ({
channel_id: item.id,
label: item.name,
@ -138,13 +143,13 @@ const mutations = {
// Identify menuItem to update
// May have more than one object to update
// Iterate it accordingly. Updating commmon sidebar now.
const menuItems = _state.menuGroup.common.menuItems;
const { menuItems } = _state.menuGroup.common;
// Update children for key `inbox`
menuItems.inbox.children = payload;
},
[types.default.SET_INBOX_ITEM](_state, { data }) {
const menuItems = _state.menuGroup.common.menuItems;
const { menuItems } = _state.menuGroup.common;
// Update children for key `inbox`
menuItems.inbox.children.push({
channel_id: data.id,
@ -157,13 +162,11 @@ const mutations = {
},
[types.default.DELETE_INBOX](_state, id) {
const menuItems = _state.menuGroup.common.menuItems;
const { menuItems } = _state.menuGroup.common;
let inboxList = menuItems.inbox.children;
inboxList = inboxList.filter(inbox => inbox.channel_id !== id);
menuItems.inbox.children = inboxList;
},
};
export default {

View file

@ -72,5 +72,8 @@
"eslint --fix",
"git add"
]
},
"scripts": {
"eslint": "eslint app/javascript"
}
}

View file

@ -30,6 +30,8 @@ AWS_REGION: ''
#chargebee
CHARGEBEE_API_KEY: ''
CHARGEBEE_SITE: ''
CHARGEBEE_WEBHOOK_USERNAME: ''
CHARGEBEE_WEBHOOK_PASSWORD: ''
#sentry
SENTRY_DSN: ''