@@ -14,6 +14,7 @@ import PolicyPage from '../account/profile/PolicyPage' | |||
import DevicesPage from '../account/DevicesPage' | |||
import AppsPage from '../account/AppsPage' | |||
import AppPage from '../account/AppPage' | |||
import BillsPage from '../account/payment/BillsPage' | |||
import AppSitePage from '../account/AppSitePage' | |||
import AppDataViewPage from '../account/AppDataViewPage' | |||
import AppConfigPage from '../account/AppConfigPage' | |||
@@ -65,6 +66,7 @@ export const router = new Router({ | |||
{ path: '/me/changePassword', component: ChangePasswordPage }, | |||
{ path: '/me/setPassword/:code', component: SetPasswordPage }, | |||
{ path: '/me/keys', component: SshKeysPage }, | |||
{ path: '/me/bills', component: BillsPage }, | |||
{ path: '/devices', component: DevicesPage }, | |||
{ path: '/apps', component: AppsPage }, | |||
{ path: '/app/:app', component: AppPage }, | |||
@@ -0,0 +1,15 @@ | |||
import config from 'config'; | |||
import { util } from '../_helpers'; | |||
export const billService = { | |||
getAllBillsByAccount, | |||
getBillByAccountAndId | |||
}; | |||
function getAllBillsByAccount(userId, messages, errors) { | |||
return fetch(`${config.apiUrl}/users/${userId}/bills`, util.getWithAuth()).then(util.handleCrudResponse(messages, errors)); | |||
} | |||
function getBillByAccountAndId(userId, billId, messages, errors) { | |||
return fetch(`${config.apiUrl}/users/${userId}/bills/${billId}`, util.getWithAuth()).then(util.handleCrudResponse(messages, errors)); | |||
} |
@@ -8,3 +8,4 @@ export * from './accountPlan.service'; | |||
export * from './network.service'; | |||
export * from './device.service'; | |||
export * from './app.service'; | |||
export * from './bill.service'; |
@@ -0,0 +1,67 @@ | |||
import { billService } from '../_services'; | |||
import { util } from '../_helpers'; | |||
const state = { | |||
loading: { | |||
bills: false, bill: false | |||
}, | |||
error: null, | |||
bills: null, | |||
bill: null | |||
}; | |||
const actions = { | |||
getAllBillsByAccount({ commit }, {userId, messages, errors}) { | |||
commit('getAllBillsByAccountRequest'); | |||
billService.getAllBillsByAccount(userId, messages, errors) | |||
.then( | |||
bills => commit('getAllBillsByAccountSuccess', bills), | |||
error => commit('getAllBillsByAccountFailure', error) | |||
); | |||
}, | |||
getBillByAccountAndId({ commit }, {userId, billId, messages, errors}) { | |||
commit('getBillByAccountAndIdRequest'); | |||
billService.getBillByAccountAndId(userId, billId, messages, errors) | |||
.then( | |||
bill => commit('getBillByAccountAndIdSuccess', bill), | |||
error => commit('getBillByAccountAndIdFailure', error) | |||
); | |||
} | |||
}; | |||
const mutations = { | |||
getAllBillsByAccountRequest(state) { | |||
state.loading.bills = true; | |||
}, | |||
getAllBillsByAccountSuccess(state, bills) { | |||
state.loading.bills = false; | |||
state.bills = bills; | |||
}, | |||
getAllBillsByAccountFailure(state, error) { | |||
state.loading.bills = false; | |||
state.error = { error }; | |||
}, | |||
getBillByAccountAndIdRequest(state) { | |||
state.loading.bill = true; | |||
}, | |||
getBillByAccountAndIdSuccess(state, bill) { | |||
state.loading.bill = false; | |||
state.bill = bill; | |||
}, | |||
getBillByAccountAndIdFailure(state, error) { | |||
state.loading.bill = false; | |||
state.error = { error }; | |||
} | |||
}; | |||
const getters = { | |||
loading: util.checkLoading(state.loading) | |||
}; | |||
export const bills = { | |||
namespaced: true, | |||
state, | |||
actions, | |||
mutations, | |||
getters | |||
}; |
@@ -13,6 +13,7 @@ import { accountPlans } from './accountPlans.module'; | |||
import { networks } from './networks.module'; | |||
import { devices } from './devices.module'; | |||
import { apps } from './apps.module'; | |||
import { bills } from './bills.module'; | |||
Vue.use(Vuex); | |||
@@ -29,7 +30,8 @@ export const store = new Vuex.Store({ | |||
accountPlans, | |||
networks, | |||
devices, | |||
apps | |||
apps, | |||
bills | |||
} | |||
}); | |||
@@ -0,0 +1,94 @@ | |||
<template> | |||
<div> | |||
<h4>{{messages.title_bills}}<span v-if="this.me === false"> - {{this.userId}}</span></h4> | |||
<table border="1"> | |||
<thead> | |||
<tr> | |||
<td>{{messages.label_bill_period}}</td> | |||
<td>{{messages.label_bill_plan}}</td> | |||
<td>{{messages.label_bill_status}}</td> | |||
<td>{{messages.label_bill_total}}</td> | |||
</tr> | |||
</thead> | |||
<tbody v-if="billObjects"> | |||
<tr v-for="bill in billObjects"> | |||
<td>{{bill.periodStart}} - {{bill.periodEnd}} ({{bill.periodLabel}})</td> | |||
<td>{{messages['plan_name_'+bill.planObject.name]}}</td> | |||
<td>{{messages['bill_status_'+bill.status]}}</td> | |||
<td> | |||
{{messages.label_bill_total_format.parseExpression({messages: messages, ...bill})}} | |||
</td> | |||
</tr> | |||
</tbody> | |||
</table> | |||
</div> | |||
</template> | |||
<script> | |||
import { mapState, mapActions, mapGetters } from 'vuex'; | |||
import { util } from '../../_helpers'; | |||
import { Settings } from 'luxon'; | |||
export default { | |||
data() { | |||
return { | |||
me: null, | |||
userId: null, | |||
linkPrefix: null, | |||
currentUser: util.currentUser(), | |||
billObjects: null | |||
}; | |||
}, | |||
computed: { | |||
...mapState('system', ['messages']), | |||
...mapState('bills', ['bills']) | |||
}, | |||
methods: { | |||
...mapActions('bills', ['getAllBillsByAccount']), | |||
...mapGetters('bills', ['loading']) | |||
}, | |||
watch: { | |||
bills (b) { | |||
if (b && b.length && b.length > 0) { | |||
const billObjects = []; | |||
for (let i=0; i<b.length; i++) { | |||
const bill = b[i]; | |||
bill['totalMajorUnits'] = bill.total / 100; | |||
bill['totalMinorUnits'] = bill.total % 100; | |||
billObjects.push(bill); | |||
} | |||
this.billObjects = billObjects; | |||
} | |||
} | |||
}, | |||
created () { | |||
this.me = this.$route.path.startsWith('/me/'); | |||
if (this.me) { | |||
this.linkPrefix = '/me'; | |||
if (this.currentUser === null) { | |||
console.warn('BillsPage.created: /me requested but no currentUser, sending to home page'); | |||
this.$router.push('/'); | |||
return; | |||
} else { | |||
this.userId = this.currentUser.uuid; | |||
} | |||
} else if (this.currentUser.admin !== true) { | |||
console.warn('BillsPage.created: not admin and path not /me, sending to /me ...'); | |||
this.$router.push('/me'); | |||
return; | |||
} else if (typeof this.$route.params.id === 'undefined' || this.$route.params.id === null) { | |||
console.warn('BillsPage.created: no id param found, sending to accounts page'); | |||
this.$router.push('/admin/accounts'); | |||
return; | |||
} else { | |||
this.userId = this.$route.params.id; | |||
this.linkPrefix = '/admin/accounts/' + this.userId; | |||
} | |||
this.getAllBillsByAccount({userId: this.userId, messages: this.messages, errors: this.errors}); | |||
} | |||
}; | |||
</script> |
@@ -151,13 +151,11 @@ | |||
if (this.me) { | |||
this.linkPrefix = '/me'; | |||
if (this.currentUser === null) { | |||
this.admin = false; | |||
console.warn('SshKeysPage.created: /me requested but no currentUser, sending to home page'); | |||
this.$router.push('/'); | |||
return; | |||
} else { | |||
this.admin = this.currentUser.admin === true; | |||
this.userId = this.currentUser.uuid; | |||
} | |||
@@ -175,15 +173,6 @@ | |||
this.userId = this.$route.params.id; | |||
this.linkPrefix = '/admin/accounts/' + this.userId; | |||
} | |||
// const user = util.currentUser(); | |||
// if (util.userHasLocale(user)) { | |||
// Settings.defaultLocale = util.jsLocale(this.user, null); | |||
// } else if (this.detectedLocale === null) { | |||
// this.detectLocale(); | |||
// } else { | |||
// Settings.defaultLocale = util.jsLocale(null, this.detectedLocale); | |||
// } | |||
this.listSshKeysByUserId({userId: this.userId, messages: this.messages, errors: this.errors}); | |||
} | |||
}; |