✨ (Account Card) Design Card
This commit is contained in:
11
package-lock.json
generated
11
package-lock.json
generated
@@ -1052,6 +1052,12 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"@types/chartist": {
|
||||||
|
"version": "0.9.46",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/chartist/-/chartist-0.9.46.tgz",
|
||||||
|
"integrity": "sha512-p29+DAkJRBVtuiTx5kObF6n/RipOWH0GeWVwYinljrwPMruy7BW+Ms6iHS4vIsHzb9c79x+opon3GJo75rlhcQ==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"@types/debug": {
|
"@types/debug": {
|
||||||
"version": "4.1.5",
|
"version": "4.1.5",
|
||||||
"resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.5.tgz",
|
"resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.5.tgz",
|
||||||
@@ -3478,6 +3484,11 @@
|
|||||||
"resolved": "https://registry.npmjs.org/charenc/-/charenc-0.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/charenc/-/charenc-0.0.2.tgz",
|
||||||
"integrity": "sha1-wKHS86cJLgN3S/qD8UwPxXkKhmc="
|
"integrity": "sha1-wKHS86cJLgN3S/qD8UwPxXkKhmc="
|
||||||
},
|
},
|
||||||
|
"chartist": {
|
||||||
|
"version": "0.11.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/chartist/-/chartist-0.11.4.tgz",
|
||||||
|
"integrity": "sha512-H4AimxaUD738/u9Mq8t27J4lh6STsLi4BQHt65nOtpLk3xyrBPaLiLMrHw7/WV9CmsjGA02WihjuL5qpSagLYw=="
|
||||||
|
},
|
||||||
"check-types": {
|
"check-types": {
|
||||||
"version": "8.0.3",
|
"version": "8.0.3",
|
||||||
"resolved": "https://registry.npmjs.org/check-types/-/check-types-8.0.3.tgz",
|
"resolved": "https://registry.npmjs.org/check-types/-/check-types-8.0.3.tgz",
|
||||||
|
|||||||
@@ -18,6 +18,7 @@
|
|||||||
"bulma-checkradio": "^2.1.0",
|
"bulma-checkradio": "^2.1.0",
|
||||||
"bulma-pricingtable": "^0.2.0",
|
"bulma-pricingtable": "^0.2.0",
|
||||||
"bulma-switch": "^2.0.0",
|
"bulma-switch": "^2.0.0",
|
||||||
|
"chartist": "^0.11.4",
|
||||||
"crypto-js": "^3.1.9-1",
|
"crypto-js": "^3.1.9-1",
|
||||||
"lightness": "^1.0.0",
|
"lightness": "^1.0.0",
|
||||||
"lodash-es": "^4.17.15",
|
"lodash-es": "^4.17.15",
|
||||||
@@ -39,6 +40,7 @@
|
|||||||
"vuex-persist": "^2.0.1"
|
"vuex-persist": "^2.0.1"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
"@types/chartist": "^0.9.46",
|
||||||
"@types/jest": "^24.0.17",
|
"@types/jest": "^24.0.17",
|
||||||
"@types/lodash-es": "^4.17.3",
|
"@types/lodash-es": "^4.17.3",
|
||||||
"@types/md5": "^2.1.33",
|
"@types/md5": "^2.1.33",
|
||||||
|
|||||||
@@ -1,15 +1,21 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="account-card box" :style="getColor(account.color)" @click="goToAccount(account._id)">
|
<div
|
||||||
|
class="account-card box"
|
||||||
|
:style="getColor(account.color)"
|
||||||
|
@click="goToAccount(account._id)"
|
||||||
|
>
|
||||||
<router-link
|
<router-link
|
||||||
:class="{ 'is-primary': !account.color, 'is-white': account.color }"
|
:class="{ 'is-primary': !account.color, 'is-white': account.color }"
|
||||||
:style="`color: ${findDarkValue(account.color)}`"
|
:style="`color: ${findDarkValue(account.color)}`"
|
||||||
:to="{ name: 'account', params: { id: account._id } }"
|
:to="{ name: 'account', params: { id: account._id } }"
|
||||||
>{{ account.name }}</router-link>
|
>{{ account.name }}</router-link
|
||||||
|
>
|
||||||
<div v-if="account.isPublic">
|
<div v-if="account.isPublic">
|
||||||
<awe-icon icon="users" />
|
<awe-icon icon="users" />
|
||||||
</div>
|
</div>
|
||||||
|
<div :id="`chart-${account._id}`" class="ct-chart ct-golden-section"></div>
|
||||||
<br />
|
<br />
|
||||||
{{ account.users && account.users.map(u => u.alias).join(', ') }}
|
{{ account.users && account.users.map((u) => u.alias).join(', ') }}
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@@ -21,11 +27,51 @@ import accountService from '@/services/AccountService'
|
|||||||
import IAccount from '@/models/IAccount'
|
import IAccount from '@/models/IAccount'
|
||||||
import IColor from '@/models/IColor'
|
import IColor from '@/models/IColor'
|
||||||
import FabButton from '@/components/FabButton.vue'
|
import FabButton from '@/components/FabButton.vue'
|
||||||
|
import ITransaction from '../models/ITransaction'
|
||||||
|
import TransactionService from '../services/TransactionService'
|
||||||
|
import Chartist from 'chartist'
|
||||||
|
import TransactionType from '../enums/TransactionType'
|
||||||
|
import colors from '../data/colors'
|
||||||
|
|
||||||
@Component
|
@Component
|
||||||
export default class AccountCard extends Vue {
|
export default class AccountCard extends Vue {
|
||||||
@Prop({ type: Object, required: true })
|
@Prop({ type: Object, required: true })
|
||||||
public account!: IAccount
|
public account!: IAccount
|
||||||
|
public transactions: ITransaction[] = []
|
||||||
|
|
||||||
|
public async mounted() {
|
||||||
|
this.transactions = await TransactionService.getAllByAccountId(
|
||||||
|
this.account._id
|
||||||
|
)
|
||||||
|
|
||||||
|
const data = {
|
||||||
|
labels: this.labels,
|
||||||
|
series: [this.sumOfTransactions]
|
||||||
|
}
|
||||||
|
|
||||||
|
const chartId = `#chart-${this.account._id}`
|
||||||
|
// tslint:disable-next-line:no-unused-expression
|
||||||
|
new Chartist.Bar(chartId, data, {})
|
||||||
|
|
||||||
|
setTimeout(() => {
|
||||||
|
const color = colors.find((c) => c.value === this.account.color)
|
||||||
|
if (!color) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
const bars = document.querySelectorAll(
|
||||||
|
`${chartId} .ct-bar`
|
||||||
|
) as NodeListOf<HTMLElement>
|
||||||
|
bars.forEach((bar) => (bar.style.stroke = color.darkValue || 'red'))
|
||||||
|
}, 500)
|
||||||
|
}
|
||||||
|
|
||||||
|
public findDarkValue(color: string): string | null {
|
||||||
|
return findDarkValue(color)
|
||||||
|
}
|
||||||
|
|
||||||
|
public goToAccount(id: string): void {
|
||||||
|
this.$router.push({ name: 'account', params: { id } })
|
||||||
|
}
|
||||||
|
|
||||||
public getColor(color: string | null): any | null {
|
public getColor(color: string | null): any | null {
|
||||||
if (!color) {
|
if (!color) {
|
||||||
@@ -37,18 +83,57 @@ export default class AccountCard extends Vue {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public findDarkValue(color: string): string | null {
|
public get amounts(): ITransaction[] {
|
||||||
return findDarkValue(color)
|
return this.transactions.filter(
|
||||||
|
(transaction) => transaction.transactionType === TransactionType.normal
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
public goToAccount(id: string): void {
|
public get labels(): string[] {
|
||||||
this.$router.push({ name: 'account', params: { id } })
|
const dates = this.amounts.map((transaction) =>
|
||||||
|
this.dateToLabel(new Date(transaction.date))
|
||||||
|
)
|
||||||
|
return [...new Set(dates)]
|
||||||
|
}
|
||||||
|
|
||||||
|
public get sumOfTransactions(): number[] {
|
||||||
|
const sortedTransactions = [...this.amounts].sort((a, b) =>
|
||||||
|
a.date < b.date ? -1 : 1
|
||||||
|
)
|
||||||
|
const groups = sortedTransactions.reduce(
|
||||||
|
(group: { [key: string]: number }, transaction: ITransaction) => {
|
||||||
|
const date = this.dateToLabel(new Date(transaction.date))
|
||||||
|
if (!(date in group)) {
|
||||||
|
group[date] = 0
|
||||||
|
}
|
||||||
|
group[date] += transaction.amount
|
||||||
|
return group
|
||||||
|
},
|
||||||
|
{}
|
||||||
|
)
|
||||||
|
return Object.values(groups)
|
||||||
|
}
|
||||||
|
|
||||||
|
private dateToLabel(date: Date): string {
|
||||||
|
return `${(date.getMonth() + 1)
|
||||||
|
.toString()
|
||||||
|
.padStart(2, '0')}/${date.getFullYear()}`
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
@import '../styles/variables';
|
@import '../styles/variables';
|
||||||
|
@import '~chartist/dist/chartist.min.css';
|
||||||
|
|
||||||
|
.ct-chart {
|
||||||
|
.ct-series-a {
|
||||||
|
.ct-bar {
|
||||||
|
stroke: blue;
|
||||||
|
stroke-width: 10px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.box {
|
.box {
|
||||||
border-radius: 8px;
|
border-radius: 8px;
|
||||||
|
|||||||
@@ -84,7 +84,11 @@ class TransactionService {
|
|||||||
return await couchService.multipleSave(transactions)
|
return await couchService.multipleSave(transactions)
|
||||||
}
|
}
|
||||||
|
|
||||||
public async getAllByAccountId(accountId: string): Promise<ITransaction[]> {
|
public async getAllByAccountId(accountId?: string): Promise<ITransaction[]> {
|
||||||
|
if (!accountId) {
|
||||||
|
return []
|
||||||
|
}
|
||||||
|
|
||||||
const response: PouchDB.Core.AllDocsResponse<
|
const response: PouchDB.Core.AllDocsResponse<
|
||||||
ITransaction
|
ITransaction
|
||||||
> = await couchService.getByPrefix<ITransaction>(`tra-${accountId}`)
|
> = await couchService.getByPrefix<ITransaction>(`tra-${accountId}`)
|
||||||
|
|||||||
@@ -5,11 +5,21 @@
|
|||||||
<ul>
|
<ul>
|
||||||
<li>
|
<li>
|
||||||
<router-link
|
<router-link
|
||||||
:to="{ name: 'account', params: { id: account._id }, hash: `#${transaction._id}` }"
|
:to="{
|
||||||
>{{ account.name }}</router-link>
|
name: 'account',
|
||||||
|
params: { id: account._id },
|
||||||
|
hash: `#${transaction._id}`
|
||||||
|
}"
|
||||||
|
>{{ account.name }}</router-link
|
||||||
|
>
|
||||||
</li>
|
</li>
|
||||||
<li class="is-active" v-if="transaction.tag && transaction.tag !== noTag">
|
<li
|
||||||
<a href="#" @click.prevent>{{ transactionTagLabel[transaction.tag].label }}</a>
|
class="is-active"
|
||||||
|
v-if="transaction.tag && transaction.tag !== noTag"
|
||||||
|
>
|
||||||
|
<a href="#" @click.prevent>{{
|
||||||
|
transactionTagLabel[transaction.tag].label
|
||||||
|
}}</a>
|
||||||
</li>
|
</li>
|
||||||
<li class="is-active">
|
<li class="is-active">
|
||||||
<a href="#" @click.prevent>{{ transaction.name }}</a>
|
<a href="#" @click.prevent>{{ transaction.name }}</a>
|
||||||
@@ -23,25 +33,32 @@
|
|||||||
<span v-if="payForLabel.length > 1">{{ payForLabel.join(', ') }}</span>
|
<span v-if="payForLabel.length > 1">{{ payForLabel.join(', ') }}</span>
|
||||||
<span v-else>{{ payForLabel[0] }}</span>
|
<span v-else>{{ payForLabel[0] }}</span>
|
||||||
d'une somme de
|
d'une somme de
|
||||||
<span
|
<span class="numeric">{{
|
||||||
class="numeric"
|
transaction.amount | money(transaction.mainCurrency)
|
||||||
>{{ transaction.amount | money(transaction.mainCurrency) }}</span>.
|
}}</span
|
||||||
|
>.
|
||||||
</div>
|
</div>
|
||||||
<div v-if="transaction.exchange" class="exchange">
|
<div v-if="transaction.exchange" class="exchange">
|
||||||
<div v-if="currencies.length">
|
<div v-if="currencies.length">
|
||||||
<hr />
|
<hr />
|
||||||
<h2 class="subtitle is-2">Taux d'échange à date</h2>
|
<h2 class="subtitle is-2">Taux d'échange aujourd'hui</h2>
|
||||||
<div class="columns is-centered">
|
<div class="columns is-centered">
|
||||||
<div class="column">
|
<div class="column">
|
||||||
<table class="table is-fullwidth is-striped is-bordered">
|
<table class="table is-fullwidth is-striped is-bordered">
|
||||||
<caption>
|
<caption>
|
||||||
<span class="numeric">{{ transaction.amount | money(transaction.mainCurrency) }}</span>
|
<span class="numeric">{{
|
||||||
|
transaction.amount | money(transaction.mainCurrency)
|
||||||
|
}}</span>
|
||||||
</caption>
|
</caption>
|
||||||
<tbody>
|
<tbody>
|
||||||
<tr v-for="(currency, k) in currencies" :key="k">
|
<tr v-for="(currency, k) in currencies" :key="k">
|
||||||
<td
|
<td class="numeric">
|
||||||
class="numeric"
|
{{
|
||||||
>{{ (transaction.amount * transaction.exchange.rates[currency.code]) | moneypad(currency) }}</td>
|
(transaction.amount *
|
||||||
|
transaction.exchange.rates[currency.code])
|
||||||
|
| moneypad(currency)
|
||||||
|
}}
|
||||||
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
@@ -49,26 +66,40 @@
|
|||||||
<div class="column">
|
<div class="column">
|
||||||
<table class="table is-fullwidth is-striped is-bordered">
|
<table class="table is-fullwidth is-striped is-bordered">
|
||||||
<caption>
|
<caption>
|
||||||
<span class="numeric">{{ 1 | money(transaction.mainCurrency) }}</span>
|
<span class="numeric">{{
|
||||||
|
1 | money(transaction.mainCurrency)
|
||||||
|
}}</span>
|
||||||
</caption>
|
</caption>
|
||||||
<tbody>
|
<tbody>
|
||||||
<tr v-for="(currency, k) in currencies" :key="k">
|
<tr v-for="(currency, k) in currencies" :key="k">
|
||||||
<td
|
<td class="numeric">
|
||||||
class="numeric"
|
{{
|
||||||
>{{ ( transaction.exchange.rates[currency.code]) | moneypad(currency) }}</td>
|
transaction.exchange.rates[currency.code]
|
||||||
|
| moneypad(currency)
|
||||||
|
}}
|
||||||
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
<div class="column">
|
<div class="column">
|
||||||
<table class="table is-hoverable is-fullwidth is-striped is-bordered">
|
<table
|
||||||
<caption>{{ $tc('transaction.money', currencies.length) }}</caption>
|
class="table is-hoverable is-fullwidth is-striped is-bordered"
|
||||||
|
>
|
||||||
|
<caption>
|
||||||
|
{{
|
||||||
|
$tc('transaction.money', currencies.length)
|
||||||
|
}}
|
||||||
|
</caption>
|
||||||
<tbody>
|
<tbody>
|
||||||
<tr v-for="(currency, k) in currencies" :key="k">
|
<tr v-for="(currency, k) in currencies" :key="k">
|
||||||
<td>{{ 1 | money(currency) }}</td>
|
<td>{{ 1 | money(currency) }}</td>
|
||||||
<td
|
<td class="numeric">
|
||||||
class="numeric"
|
{{
|
||||||
>{{ (1 / transaction.exchange.rates[currency.code]) | moneypad(transaction.mainCurrency) }}</td>
|
(1 / transaction.exchange.rates[currency.code])
|
||||||
|
| moneypad(transaction.mainCurrency)
|
||||||
|
}}
|
||||||
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
@@ -77,7 +108,8 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div v-else>
|
<div v-else>
|
||||||
<online-view @online="retrieveExchange" />Le taux d'échange n'a pas pu être récupéré.
|
<online-view @online="retrieveExchange" />Le taux d'échange n'a pas pu
|
||||||
|
être récupéré.
|
||||||
</div>
|
</div>
|
||||||
<div class="buttons is-centered" v-if="!account.archive">
|
<div class="buttons is-centered" v-if="!account.archive">
|
||||||
<router-link
|
<router-link
|
||||||
@@ -85,8 +117,11 @@
|
|||||||
tag="button"
|
tag="button"
|
||||||
class="button"
|
class="button"
|
||||||
:to="{ name: 'transaction-update', params: { id } }"
|
:to="{ name: 'transaction-update', params: { id } }"
|
||||||
>modifier</router-link>
|
>modifier</router-link
|
||||||
<confirm-button class="is-danger" @confirm="removeTransaction">supprimer</confirm-button>
|
>
|
||||||
|
<confirm-button class="is-danger" @confirm="removeTransaction"
|
||||||
|
>supprimer</confirm-button
|
||||||
|
>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
Reference in New Issue
Block a user