mirror of
https://github.com/mokuappio/serverless-invoices.git
synced 2025-10-28 16:31:07 -04:00
Abstract backend functionality to be able to easily switch out backend implementation.
This commit is contained in:
@ -8,26 +8,26 @@ import app from '@/main';
|
|||||||
Vue.use(VueI18Next);
|
Vue.use(VueI18Next);
|
||||||
|
|
||||||
i18next
|
i18next
|
||||||
.use(LanguageDetector)
|
.use(LanguageDetector)
|
||||||
.use(Backend);
|
.use(Backend);
|
||||||
|
|
||||||
const initialized = i18next.init({
|
const initialized = i18next.init({
|
||||||
fallbackLng: 'en',
|
fallbackLng: 'en',
|
||||||
whitelist: ['en', 'fr', 'et', 'fa', 'bn', 'es'],
|
whitelist: ['en', 'fr', 'et', 'fa', 'bn', 'es'],
|
||||||
backend: {
|
backend: {
|
||||||
loadPath: `${window.location.origin}/locales/{{lng}}/{{ns}}.json`,
|
loadPath: `${window.location.origin}/locales/{{lng}}/{{ns}}.json`,
|
||||||
},
|
},
|
||||||
detection: {
|
detection: {
|
||||||
order: ['querystring', 'path', 'localStorage', 'navigator'],
|
order: ['querystring', 'path', 'localStorage', 'navigator'],
|
||||||
lookupQuerystring: 'lang',
|
lookupQuerystring: 'lang',
|
||||||
caches: ['localStorage'],
|
caches: ['localStorage'],
|
||||||
checkWhitelist: true,
|
checkWhitelist: true,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
initialized.then(() => app.$store.dispatch('language/initLanguage', i18next.language));
|
initialized.then(() => app.$store.dispatch('language/initLanguage', i18next.language));
|
||||||
|
|
||||||
const i18n = new VueI18Next(i18next, {
|
const i18n = new VueI18Next(i18next, {
|
||||||
loadComponentNamespace: true,
|
loadComponentNamespace: true,
|
||||||
});
|
});
|
||||||
|
|
||||||
i18n.initialized = initialized;
|
i18n.initialized = initialized;
|
||||||
|
|||||||
@ -5,3 +5,7 @@ storage.config({
|
|||||||
version: 1.0,
|
version: 1.0,
|
||||||
storeName: 'default',
|
storeName: 'default',
|
||||||
});
|
});
|
||||||
|
|
||||||
|
export default {
|
||||||
|
type: 'local',
|
||||||
|
};
|
||||||
|
|||||||
9
src/services/adapters/http.adapter.js
Normal file
9
src/services/adapters/http.adapter.js
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
const axios = null;
|
||||||
|
|
||||||
|
class HttpAdapter {
|
||||||
|
async get(uri) {
|
||||||
|
return axios.get(uri);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default new HttpAdapter();
|
||||||
65
src/services/adapters/local.adapter.js
Normal file
65
src/services/adapters/local.adapter.js
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
import storage from 'localforage';
|
||||||
|
import { removeVuexORMFlags } from '@/utils/helpers';
|
||||||
|
|
||||||
|
class LocalAdapter {
|
||||||
|
async get(uri) {
|
||||||
|
const parts = uri.split('/');
|
||||||
|
|
||||||
|
if (parts.length === 1) {
|
||||||
|
return storage.getItem(parts[0]) || [];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (parts.length === 2) {
|
||||||
|
return (await storage.getItem(parts[0]))
|
||||||
|
.find(it => it.id === parts[1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
async post(uri, data) {
|
||||||
|
const items = await this.get(uri);
|
||||||
|
|
||||||
|
removeVuexORMFlags(data);
|
||||||
|
items.push(data);
|
||||||
|
|
||||||
|
return storage.setItem(uri, items);
|
||||||
|
}
|
||||||
|
|
||||||
|
async patch(uri, data) {
|
||||||
|
const parts = uri.split('/');
|
||||||
|
|
||||||
|
if (parts.length === 2) {
|
||||||
|
const items = await this.get(parts[0]);
|
||||||
|
|
||||||
|
const index = items.findIndex(it => it.id === parts[1]);
|
||||||
|
removeVuexORMFlags(data);
|
||||||
|
items[index] = data;
|
||||||
|
|
||||||
|
return storage.setItem(parts[0], items);
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
async put(uri, data) {
|
||||||
|
return storage.setItem(uri, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
async delete(uri) {
|
||||||
|
const parts = uri.split('/');
|
||||||
|
|
||||||
|
if (parts.length === 2) {
|
||||||
|
const items = await this.get(parts[0]);
|
||||||
|
|
||||||
|
const index = items.findIndex(it => it.id === parts[1]);
|
||||||
|
items.splice(index, 1);
|
||||||
|
|
||||||
|
return storage.setItem(parts[0], items);
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default new LocalAdapter();
|
||||||
4
src/services/adapters/wordpress.adapter.js
Normal file
4
src/services/adapters/wordpress.adapter.js
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
class WordpressAdapter {
|
||||||
|
}
|
||||||
|
|
||||||
|
export default new WordpressAdapter();
|
||||||
@ -1,37 +1,20 @@
|
|||||||
import storage from 'localforage';
|
import data from '@/services/data.service';
|
||||||
import { removeVuexORMFlags } from '@/utils/helpers';
|
|
||||||
|
|
||||||
class BankAccountService {
|
class BankAccountService {
|
||||||
async getBankAccounts() {
|
async getBankAccounts() {
|
||||||
const bankAccounts = await storage.getItem('bank_accounts');
|
return data.get('bank_accounts');
|
||||||
|
|
||||||
return bankAccounts || [];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async getBankAccount(bankAccountId) {
|
async getBankAccount(bankAccountId) {
|
||||||
const bankAccounts = await this.getBankAccounts();
|
return data.get(`bank_accounts/${bankAccountId}`);
|
||||||
return bankAccounts.find(bank_account => bank_account.id === bankAccountId);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async createBankAccount(bankAccount) {
|
async createBankAccount(bankAccount) {
|
||||||
return this.saveBankAccount(bankAccount);
|
return data.post('bank_accounts', bankAccount);
|
||||||
}
|
}
|
||||||
|
|
||||||
async updateBankAccount(bankAccount) {
|
async updateBankAccount(bankAccount) {
|
||||||
return this.saveBankAccount(bankAccount);
|
return data.patch(`bank_accounts/${bankAccount.id}`, bankAccount);
|
||||||
}
|
|
||||||
|
|
||||||
async saveBankAccount(bankAccount) {
|
|
||||||
const bankAccounts = await this.getBankAccounts();
|
|
||||||
const index = bankAccounts.findIndex(item => item.id === bankAccount.id);
|
|
||||||
removeVuexORMFlags(bankAccount);
|
|
||||||
if (index === -1) {
|
|
||||||
bankAccounts.push(bankAccount);
|
|
||||||
} else {
|
|
||||||
bankAccounts[index] = bankAccount;
|
|
||||||
}
|
|
||||||
await storage.setItem('bank_accounts', bankAccounts);
|
|
||||||
return bankAccount;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,45 +1,24 @@
|
|||||||
import storage from 'localforage';
|
import data from '@/services/data.service';
|
||||||
import { removeVuexORMFlags } from '@/utils/helpers';
|
|
||||||
|
|
||||||
class ClientService {
|
class ClientService {
|
||||||
async getClients() {
|
async getClients() {
|
||||||
const clients = await storage.getItem('clients');
|
return data.get('clients');
|
||||||
|
|
||||||
return clients || [];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async getClient(clientId) {
|
async getClient(clientId) {
|
||||||
const clients = await this.getClients();
|
return data.get(`clients/${clientId}`);
|
||||||
return clients.find(client => client.id === clientId);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async createClient(client) {
|
async createClient(client) {
|
||||||
return this.saveClient(client);
|
return data.post('clients', client);
|
||||||
}
|
}
|
||||||
|
|
||||||
async updateClient(client) {
|
async updateClient(client) {
|
||||||
return this.saveClient(client);
|
return data.patch(`clients/${client.id}`, client);
|
||||||
}
|
}
|
||||||
|
|
||||||
async deleteClient(clientId) {
|
async deleteClient(clientId) {
|
||||||
const clients = await this.getClients();
|
return data.delete(`clients/${clientId}`);
|
||||||
const index = clients.findIndex(item => item.id === clientId);
|
|
||||||
clients.splice(index, 1);
|
|
||||||
return storage.setItem('clients', clients);
|
|
||||||
}
|
|
||||||
|
|
||||||
async saveClient(client) {
|
|
||||||
const clients = await this.getClients();
|
|
||||||
const index = clients.findIndex(item => item.id === client.id);
|
|
||||||
removeVuexORMFlags(client);
|
|
||||||
|
|
||||||
if (index === -1) {
|
|
||||||
clients.push(client);
|
|
||||||
} else {
|
|
||||||
clients[index] = client;
|
|
||||||
}
|
|
||||||
await storage.setItem('clients', clients);
|
|
||||||
return client;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
40
src/services/data.service.js
Normal file
40
src/services/data.service.js
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
import storage from '@/config/storage.config';
|
||||||
|
import local from '@/services/adapters/local.adapter';
|
||||||
|
import http from '@/services/adapters/http.adapter';
|
||||||
|
import wordpress from '@/services/adapters/wordpress.adapter';
|
||||||
|
|
||||||
|
class DataService {
|
||||||
|
adapter = null;
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
if (storage.type === 'local') {
|
||||||
|
this.adapter = local;
|
||||||
|
} else if (storage.type === 'http') {
|
||||||
|
this.adapter = http;
|
||||||
|
} else if (storage.type === 'wordpress') {
|
||||||
|
this.adapter = wordpress;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
get(uri) {
|
||||||
|
return this.adapter.get(uri);
|
||||||
|
}
|
||||||
|
|
||||||
|
post(uri, data) {
|
||||||
|
return this.adapter.post(uri, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
patch(uri, data) {
|
||||||
|
return this.adapter.patch(uri, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
put(uri, data) {
|
||||||
|
return this.adapter.put(uri, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
delete(uri) {
|
||||||
|
return this.adapter.delete(uri);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default new DataService();
|
||||||
@ -1,22 +1,19 @@
|
|||||||
import storage from 'localforage';
|
import { validate } from '@/utils/helpers';
|
||||||
import {
|
import data from '@/services/data.service';
|
||||||
validate, removeVuexORMFlags,
|
|
||||||
} from '@/utils/helpers';
|
|
||||||
|
|
||||||
class InvoiceService {
|
class InvoiceService {
|
||||||
async getInvoices() {
|
async getInvoices() {
|
||||||
const invoices = await storage.getItem('invoices');
|
return data.get('invoices');
|
||||||
return invoices || [];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async getInvoice(invoiceId) {
|
async getInvoice(invoiceId) {
|
||||||
const invoices = await this.getInvoices();
|
return data.get(`invoices/${invoiceId}`);
|
||||||
return invoices.find(invoice => invoice.id === invoiceId);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async createInvoice(invoice) {
|
async createInvoice(invoice) {
|
||||||
delete invoice.client;
|
delete invoice.client;
|
||||||
return this.saveInvoice(invoice);
|
|
||||||
|
return data.post('invoices', invoice);
|
||||||
}
|
}
|
||||||
|
|
||||||
async updateInvoice(invoice) {
|
async updateInvoice(invoice) {
|
||||||
@ -33,14 +30,11 @@ class InvoiceService {
|
|||||||
return Promise.reject(res);
|
return Promise.reject(res);
|
||||||
}
|
}
|
||||||
|
|
||||||
return this.saveInvoice(invoice);
|
return data.patch(`invoices/${invoice.id}`, invoice);
|
||||||
}
|
}
|
||||||
|
|
||||||
async deleteInvoice(invoiceId) {
|
async deleteInvoice(invoiceId) {
|
||||||
const invoices = await this.getInvoices();
|
return data.delete(`invoices/${invoiceId}`);
|
||||||
const index = invoices.findIndex(item => item.id === invoiceId);
|
|
||||||
invoices.splice(index, 1);
|
|
||||||
return storage.setItem('invoices', invoices);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async bookInvoice(invoice) {
|
async bookInvoice(invoice) {
|
||||||
@ -83,22 +77,6 @@ class InvoiceService {
|
|||||||
invoice.status = 'booked';
|
invoice.status = 'booked';
|
||||||
return this.updateInvoice(invoice);
|
return this.updateInvoice(invoice);
|
||||||
}
|
}
|
||||||
|
|
||||||
async saveInvoice(invoice) {
|
|
||||||
const invoices = await this.getInvoices();
|
|
||||||
const index = invoices.findIndex(item => item.id === invoice.id);
|
|
||||||
|
|
||||||
delete invoice.client;
|
|
||||||
removeVuexORMFlags(invoice);
|
|
||||||
|
|
||||||
if (index === -1) {
|
|
||||||
invoices.push(invoice);
|
|
||||||
} else {
|
|
||||||
invoices[index] = invoice;
|
|
||||||
}
|
|
||||||
await storage.setItem('invoices', invoices);
|
|
||||||
return invoice;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export default new InvoiceService();
|
export default new InvoiceService();
|
||||||
|
|||||||
@ -1,48 +1,28 @@
|
|||||||
import storage from 'localforage';
|
import data from '@/services/data.service';
|
||||||
import { removeVuexORMFlags } from '@/utils/helpers';
|
|
||||||
|
|
||||||
class TaxService {
|
class TaxService {
|
||||||
async getTaxes() {
|
getTaxes() {
|
||||||
const taxes = await storage.getItem('taxes');
|
return data.get('taxes');
|
||||||
|
|
||||||
return taxes || [];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async getTax(taxId) {
|
getTax(taxId) {
|
||||||
const taxes = await this.getTaxes();
|
return data.get(`taxes/${taxId}`);
|
||||||
return taxes.find(tax => tax.id === taxId);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async createTax(tax) {
|
createTax(tax) {
|
||||||
return this.saveTax(tax);
|
return data.post('taxes', tax);
|
||||||
}
|
}
|
||||||
|
|
||||||
async updateTax(tax) {
|
updateTax(tax) {
|
||||||
return this.saveTax(tax);
|
return data.patch(`taxes/${tax.id}`, tax);
|
||||||
}
|
}
|
||||||
|
|
||||||
async deleteTax(taxId) {
|
deleteTax(taxId) {
|
||||||
const taxes = await this.getTaxes();
|
return data.delete(`taxes/${taxId}`);
|
||||||
const index = taxes.findIndex(item => item.id === taxId);
|
|
||||||
taxes.splice(index, 1);
|
|
||||||
return this.setTaxes(taxes);
|
|
||||||
}
|
|
||||||
|
|
||||||
async saveTax(tax) {
|
|
||||||
const taxes = await this.getTaxes();
|
|
||||||
const index = taxes.findIndex(item => item.id === tax.id);
|
|
||||||
removeVuexORMFlags(tax);
|
|
||||||
if (index === -1) {
|
|
||||||
taxes.push(tax);
|
|
||||||
} else {
|
|
||||||
taxes[index] = tax;
|
|
||||||
}
|
|
||||||
await this.setTaxes(taxes);
|
|
||||||
return tax;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
setTaxes(taxes) {
|
setTaxes(taxes) {
|
||||||
return storage.setItem('taxes', taxes);
|
return data.put('taxes', taxes);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,8 +1,8 @@
|
|||||||
import storage from 'localforage';
|
import data from '@/services/data.service';
|
||||||
|
|
||||||
class TeamService {
|
class TeamService {
|
||||||
async getTeam() {
|
async getTeam() {
|
||||||
let team = await storage.getItem('team');
|
let team = await data.get('team');
|
||||||
if (!team) {
|
if (!team) {
|
||||||
team = {
|
team = {
|
||||||
company_name: null,
|
company_name: null,
|
||||||
@ -26,7 +26,7 @@ class TeamService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async updateTeam(team) {
|
async updateTeam(team) {
|
||||||
return storage.setItem('team', team);
|
return data.put('team', team);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,31 +1,31 @@
|
|||||||
import app from '../main';
|
import app from '../main';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
namespaced: true,
|
namespaced: true,
|
||||||
state: {
|
state: {
|
||||||
lang: null,
|
lang: null,
|
||||||
all: [
|
all: [
|
||||||
{ name: 'English', code: 'en' },
|
{ name: 'English', code: 'en' },
|
||||||
{ name: 'French', code: 'fr' },
|
{ name: 'French', code: 'fr' },
|
||||||
{ name: 'Estonian', code: 'et' },
|
{ name: 'Estonian', code: 'et' },
|
||||||
{ name: 'Persian', code: 'fa' },
|
{ name: 'Persian', code: 'fa' },
|
||||||
{ name: 'Spanish', code: 'es' },
|
{ name: 'Spanish', code: 'es' },
|
||||||
{ name: 'Bangla', code: 'bn' },
|
{ name: 'Bangla', code: 'bn' },
|
||||||
],
|
],
|
||||||
|
},
|
||||||
|
mutations: {
|
||||||
|
lang(state, lang) {
|
||||||
|
state.lang = lang;
|
||||||
},
|
},
|
||||||
mutations: {
|
},
|
||||||
lang(state, lang) {
|
actions: {
|
||||||
state.lang = lang;
|
changeLanguage({ commit }, lang) {
|
||||||
},
|
app.$i18n.i18next.changeLanguage(lang.code);
|
||||||
|
app.$router.push({ query: { ...app.$route.query, lang: lang.code } });
|
||||||
|
commit('lang', lang);
|
||||||
},
|
},
|
||||||
actions: {
|
initLanguage({ commit, state }, code) {
|
||||||
changeLanguage({ commit }, lang) {
|
commit('lang', state.all.find(lang => lang.code === code));
|
||||||
app.$i18n.i18next.changeLanguage(lang.code);
|
|
||||||
app.$router.push({ query: {...app.$route.query, lang: lang.code } });
|
|
||||||
commit('lang', lang);
|
|
||||||
},
|
|
||||||
initLanguage({ commit, state }, code) {
|
|
||||||
commit('lang', state.all.find(lang => lang.code === code));
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
|
},
|
||||||
};
|
};
|
||||||
Reference in New Issue
Block a user