Files
expense/src/components/Input.vue
T
2021-05-15 17:24:48 +02:00

226 lines
6.1 KiB
Vue

<template>
<b-col md="6">
<b-card no-body>
<b-card-header :header-bg-variant="color" header-text-variant="white" class="container-fluid">
<b-row>
<b-col md="10">
<h3 class="w-75 p-3">{{ title }}</h3>
</b-col>
<b-col md="2" class="float-right align-self-center">
<b-button @click="add()" variant="primary" size="lg"><b-icon-plus /></b-button>
</b-col>
</b-row>
</b-card-header>
<b-card-body>
<b-table :fields="fields" :items="data" responsive="sm" v-model="currentItems">
<template #cell(index)="data">
{{ data.index + 1 }}
</template>
<template #cell(options)="data">
<b-button-group size="sm">
<b-button @click="toggleDetails(data)" v-b-tooltip.hover :title="data.detailsShowing ? 'Cancel' : 'Edit'" :variant="data.detailsShowing ? 'outline-danger' : 'primary'">
<b-icon-x-square v-if="data.detailsShowing" />
<b-icon-pencil-square v-else />
</b-button>
<b-button @click="askDelete(data)" v-b-tooltip.hover title="Remove" variant="danger"><b-icon-trash /></b-button>
</b-button-group>
</template>
<template #cell()="data">
{{ data.value }}
</template>
<template #cell(amount)="data">
{{ data.item.amount | currency }}
</template>
<template #cell(frequency)="data">
{{ $enums.Frequency.byId(data.item.frequency).name }}
</template>
<template #cell(tags)="data">
{{ (data.item.tags ? data.item.tags.length : 0) }}
</template>
<template #row-details="row">
<b-card>
<b-form @submit.prevent="save(row)">
<b-form-group
id="name-group"
label="Name:"
label-for="name">
<b-form-input
id="name"
v-model="editingCache.name"
type="text"
placeholder="Name"
required></b-form-input>
</b-form-group>
<b-form-group
id="amount-group"
label="Amount:"
label-for="amount">
<b-input-group append="€" class="mb-2 mr-sm-2 mb-sm-0">
<b-form-input
id="amount"
v-model="editingCache.amount"
type="number"
placeholder="0,00"
step="0.01"
min="0.01"
required></b-form-input>
</b-input-group>
</b-form-group>
<b-form-group
id="frequency-group"
label="Frequency:"
label-for="frequency">
<b-form-select
id="frequency"
v-model="editingCache.frequency"
type="text"
:options="$enums.Frequency.options()"
required></b-form-select>
</b-form-group>
<b-form-group
id="tags-group"
description="Enter new tags separated by comma or semicolon"
label="Tags:"
label-for="tags">
<b-form-tags
id="tags"
separator=",;"
v-model="editingCache.tags"></b-form-tags>
</b-form-group>
<b-button type="submit" variant="success"><b-icon-check /> Save</b-button>
</b-form>
</b-card>
</template>
</b-table>
</b-card-body>
</b-card>
</b-col>
</template>
<script>
import Vue from 'vue'
import Frequency from '../enums/Frequency'
export default {
name: 'Input',
enums: {
Frequency
},
props: [
'title',
'color',
'entries'
],
data () {
return {
fields: [
{
key: 'index',
label: '#'
},
'name',
'amount',
'frequency',
'tags',
{
key: 'options',
label: ''
}
],
data: [],
currentItems: [],
editingCache: undefined,
editing: undefined
}
},
mounted () {
this.$set(this, 'data', this.$props.entries)
},
methods: {
add () {
this.data.push({
name: '',
amount: 1.00,
frequency: 0
})
this.toggleDetails({index: this.data.length - 1, toggleDetails: () => {}})
},
askDelete (row) {
// ask before deletion
this.$bvModal.msgBoxConfirm(`Please confirm that you want to delete '${row.item.name}'?`, {
title: 'Are you sure?',
size: 'sm',
buttonSize: 'sm',
okVariant: 'danger',
okTitle: 'Yes',
cancelTitle: 'No',
footerClass: 'p-2',
hideHeaderClose: false,
centered: true
})
.then(confirmedDelete => {
if (!confirmedDelete) return
this.data.splice(row.index, 1)
})
},
save (row) {
// override active data with from cache
this.$set(this.data, row.index, this.editingCache)
this.toggleDetails(row)
},
toggleDetails (row) {
// close all open details
this.currentItems.forEach((item, i) => {
if (i === row.index) return
this.$set(item, '_showDetails', false)
})
// create (or reset) local copy for form data
if (row.detailsShowing) {
this.editingCache = undefined
} else {
this.editingCache = Vue.util.extend({}, row.item)
}
row.toggleDetails()
}
},
watch: {
data: {
deep: true,
handler () {
this.$emit('input', this.data)
}
},
entries: {
deep: true,
handler () {
this.$set(this, 'data', this.$props.entries)
}
}
}
}
</script>
<style>
/* highlight selected row */
.b-table-has-details {
background: var(--gray);
color: var(--white);
}
.b-table-has-details + tr {
background: var(--gray);
}
</style>