Feat: Display tags in config and add colors to tag
This commit is contained in:
parent
877c269ee4
commit
bf788d2e9e
@ -4,6 +4,7 @@ tags:
|
||||
name: Cash
|
||||
variant: info
|
||||
icon: money-bill-wave
|
||||
color: '#78e08f'
|
||||
words:
|
||||
- RETRAIT
|
||||
|
||||
@ -11,6 +12,7 @@ tags:
|
||||
name: CB
|
||||
variant: info
|
||||
icon: credit-card
|
||||
color: "#4a69bd"
|
||||
words:
|
||||
- PAIEMENT
|
||||
|
||||
@ -19,6 +21,7 @@ tags:
|
||||
variant: info
|
||||
icon: directions
|
||||
invert: true
|
||||
color: "#f6b93b"
|
||||
words:
|
||||
- PAIEMENT
|
||||
- RETRAIT
|
||||
@ -27,6 +30,7 @@ tags:
|
||||
name: Autoroute
|
||||
variant: danger
|
||||
icon: road
|
||||
color: "#eb2f06"
|
||||
words:
|
||||
- AUTOROUTE
|
||||
- APRR
|
||||
@ -35,6 +39,7 @@ tags:
|
||||
name: Essence
|
||||
variant: danger
|
||||
icon: charging-station
|
||||
color: "#0c2461"
|
||||
words:
|
||||
- CARBU
|
||||
- TOTAL
|
||||
@ -46,6 +51,7 @@ tags:
|
||||
name: Courses
|
||||
variant: warning
|
||||
icon: shopping-cart
|
||||
color: "#665191"
|
||||
words:
|
||||
- BIOCOOP
|
||||
- LA VIE CLAIRE
|
||||
|
@ -66,7 +66,6 @@ export default {
|
||||
<style scope>
|
||||
.container {
|
||||
position: relative;
|
||||
height: 40vh;
|
||||
width: 80vw;
|
||||
height: 420px;
|
||||
}
|
||||
</style>
|
||||
|
@ -4,7 +4,6 @@ export function appendTag (row, keywords, field = 'Libellé') {
|
||||
// if row.libellé contains one of words and not invert it gets tagged
|
||||
// if row.libellé contains no words and invert it gets tagged
|
||||
// according to keywords [{name: string, words: [], invert: bool}]
|
||||
// row['tags'] =
|
||||
row.tags = keywords.filter(k => {
|
||||
return strContains(row[field], k.words, k.invert)
|
||||
})
|
||||
@ -17,17 +16,17 @@ function strContains (string, words, invert) {
|
||||
}
|
||||
if (invert) {
|
||||
return words.every(v => {
|
||||
return string.indexOf(v) < 0
|
||||
return string.toLowerCase().indexOf(v.toLowerCase()) < 0
|
||||
})
|
||||
} else {
|
||||
return words.some(v => {
|
||||
return string.indexOf(v) >= 0
|
||||
return string.toLowerCase().indexOf(v.toLowerCase()) >= 0
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
export function formatDate (row, field = 'Date') {
|
||||
row[field] = moment(row[field], 'DD/MM/YYYY', true)
|
||||
row[field] = moment(row[field], 'DD/MM/YYYY', true)
|
||||
}
|
||||
|
||||
export function total (row, field = 'Montant') {
|
||||
|
@ -22,11 +22,15 @@ export default {
|
||||
},
|
||||
tags: (state) => {
|
||||
return state.tags
|
||||
},
|
||||
tag: (state) => (tagname) => {
|
||||
return state.tags[tagname.toLowerCase()]
|
||||
}
|
||||
},
|
||||
mutations: {
|
||||
SET_TAGS: (state, { tags }) => {
|
||||
state.tags = tags
|
||||
state.tags = Object.keys(tags)
|
||||
.reduce((c, k) => (c[k.toLowerCase()] = tags[k], c), {})
|
||||
}
|
||||
},
|
||||
actions: {
|
||||
@ -42,6 +46,9 @@ export default {
|
||||
context.commit('SET_TAGS', { tags: parsed.tags })
|
||||
}
|
||||
})
|
||||
},
|
||||
edit_tag (context, tag) {
|
||||
console.log(tag)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,5 @@
|
||||
import { readdir, readFile } from 'fs'
|
||||
import Vue from 'vue'
|
||||
import path from 'path'
|
||||
import Papa from 'papaparse'
|
||||
import moment from 'moment'
|
||||
@ -7,41 +8,45 @@ import { appendTag, formatDate } from '../../libs/data_processing'
|
||||
export default {
|
||||
namespaced: true,
|
||||
state: {
|
||||
csv_files: [],
|
||||
rows: {
|
||||
data: [],
|
||||
meta: {
|
||||
fields: []
|
||||
}
|
||||
},
|
||||
csv: {},
|
||||
start: moment().subtract(1, 'months'),
|
||||
end: moment()
|
||||
},
|
||||
getters: {
|
||||
csvs: (state) => {
|
||||
return state.csv_files
|
||||
// return array of csv filename
|
||||
return Object.keys(state.csv)
|
||||
},
|
||||
rows: (state) => {
|
||||
return state.rows.data
|
||||
// return all data stored in csv
|
||||
return [ ...new Set(Object.values(state.csv).map(csv => csv.data)
|
||||
.reduce((acc, d) => acc.concat(d), [])
|
||||
)]
|
||||
},
|
||||
present: (state) => {
|
||||
return state.rows.data.length > 0
|
||||
present: (state, getters) => {
|
||||
// is there any datas
|
||||
return getters.rows.length > 0
|
||||
},
|
||||
spending_rows: (state, getters) => {
|
||||
// return data with negatives 'Montant'
|
||||
return getters.rows.filter(x => x.Montant < 0)
|
||||
},
|
||||
start: (state) => {
|
||||
// Start date
|
||||
return state.start.format(moment.HTML5_FMT.DATE)
|
||||
},
|
||||
end: (state) => {
|
||||
// End date
|
||||
return state.end.format(moment.HTML5_FMT.DATE)
|
||||
},
|
||||
date_filter_rows: (state, getters) => {
|
||||
// return rows filtered by date
|
||||
return getters.spending_rows.filter(x => {
|
||||
return (x.Date >= state.start) & (x.Date < state.end)
|
||||
})
|
||||
},
|
||||
tag_filter_rows: (state, getters) => (tags, invert) => {
|
||||
// return rows filtered by date then by tags
|
||||
if (tags) {
|
||||
return getters.date_filter_rows.filter(row => {
|
||||
if (invert) {
|
||||
@ -65,6 +70,7 @@ export default {
|
||||
}
|
||||
},
|
||||
libelle_filter_rows: (state, getters) => (words, invert) => {
|
||||
// return rows filtered by present of words in 'Libellé'
|
||||
if (!words) {
|
||||
return getters.date_filter_rows
|
||||
}
|
||||
@ -87,11 +93,8 @@ export default {
|
||||
SET_CSV_FILES: (state, { csvs }) => {
|
||||
state.csv_files = csvs
|
||||
},
|
||||
SET_DATA: (state, { data }) => {
|
||||
state.rows = data
|
||||
},
|
||||
APPEND_DATA: (state, { content }) => {
|
||||
state.rows.push(content)
|
||||
SET_DATA: (state, { filename, data }) => {
|
||||
Vue.set(state.csv, filename, data)
|
||||
},
|
||||
SET_START: (state, { start }) => {
|
||||
state.start = start
|
||||
@ -129,11 +132,14 @@ export default {
|
||||
header: true
|
||||
}
|
||||
var parsed = Papa.parse(content, parseConfig)
|
||||
context.dispatch('clean_store_data', parsed)
|
||||
context.dispatch('clean_store_data', {
|
||||
filename: csv,
|
||||
parsed: parsed
|
||||
})
|
||||
}
|
||||
})
|
||||
},
|
||||
clean_store_data (context, parsed) {
|
||||
clean_store_data (context, { filename, parsed }) {
|
||||
var tags = Object.values(context.rootGetters['config/tags'])
|
||||
parsed.data = parsed.data.filter(x => x.Libellé !== undefined)
|
||||
parsed.data.forEach(row => {
|
||||
@ -141,13 +147,15 @@ export default {
|
||||
formatDate(row, 'Date')
|
||||
})
|
||||
|
||||
context.commit('SET_DATA', { data: parsed })
|
||||
context.commit('SET_DATA',
|
||||
{ filename: filename, data: parsed }
|
||||
)
|
||||
},
|
||||
set_start (context, start) {
|
||||
context.commit('SET_START', { start: moment(start)})
|
||||
context.commit('SET_START', { start: moment(start) })
|
||||
},
|
||||
set_end (context, end) {
|
||||
context.commit('SET_END', { end: moment(end)})
|
||||
context.commit('SET_END', { end: moment(end) })
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,62 @@
|
||||
<template>
|
||||
<div class="tags">
|
||||
<h1>Fichiers CSV</h1>
|
||||
<p>
|
||||
Les fichiers csv sont cherché dans <span class="datadir">{{ data_dir }}</span>
|
||||
<!--
|
||||
<b-button variant="link" @click="open_filebrowser(data_dir)"> Ouvrir <font-awesome-icon icon="folder-open" class="fa"/></b-button>
|
||||
-->
|
||||
<b-list-group>
|
||||
<b-list-group-item v-for="csv in csvs">
|
||||
{{ csv }}
|
||||
</b-list-group-item>
|
||||
</b-list-group>
|
||||
</p>
|
||||
<h1>Tags</h1>
|
||||
<b-list-group>
|
||||
<b-list-group-item v-for="tag in tags">
|
||||
<tag-config :tagname="tag.name"></tag-config>
|
||||
</b-list-group-item>
|
||||
</b-list-group>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { mapGetters, mapActions } from 'vuex'
|
||||
import { shell } from 'electron'
|
||||
import tagConfig from '../components/tag_config'
|
||||
|
||||
export default {
|
||||
name: 'home',
|
||||
components: {
|
||||
'tag-config': tagConfig
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
file: ''
|
||||
}
|
||||
},
|
||||
mounted: function () {
|
||||
},
|
||||
computed: {
|
||||
...mapGetters({
|
||||
'data_dir': 'config/data_dir',
|
||||
'csvs': 'datas/csvs',
|
||||
'tags': 'config/tags'
|
||||
})
|
||||
},
|
||||
methods: {
|
||||
...mapActions('datas', [
|
||||
]),
|
||||
open_filebrowser (dir) {
|
||||
console.log("plop")
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.datadir {
|
||||
font-weight: bold;
|
||||
}
|
||||
</style>
|
||||
|
@ -5,7 +5,7 @@
|
||||
<b-container fluid>
|
||||
<b-row class="date-selector">
|
||||
<b-col sm="1"><label for="start"> Entre </label> </b-col>
|
||||
<b-col sm="4">
|
||||
<b-col sm="3">
|
||||
<b-form-input id="start" type="date" :value="start" @input="set_start"></b-form-input>
|
||||
</b-col>
|
||||
<b-col sm="1"><label for="end"> et </label></b-col>
|
||||
@ -18,7 +18,7 @@
|
||||
<b-card-group deck class="mb-3">
|
||||
<box @click.native="set_tags_filter([])"></box>
|
||||
<box @click.native="set_tags_filter(['cash'])" tagname="cash"></box>
|
||||
<box @click.native="set_tags_filter(['CB'])" tagname="CB"></box>
|
||||
<box @click.native="set_tags_filter(['cb'])" tagname="cb"></box>
|
||||
<box @click.native="set_tags_filter(['virements'])" tagname="virements"></box>
|
||||
</b-card-group>
|
||||
|
||||
@ -26,7 +26,7 @@
|
||||
|
||||
<b-table striped hover :items="filtered_rows" :fields='fields'>
|
||||
<template slot="tags" slot-scope="data">
|
||||
<div v-for="tag in data.item.tags">
|
||||
<div v-for="tag in data.item.tags" :key="tag.name">
|
||||
<div v-if="tag.name !== 'Tout'">
|
||||
<font-awesome-icon :icon="tag.icon" class="fa"/>
|
||||
</div>
|
||||
|
Loading…
Reference in New Issue
Block a user