Commit 5f5bc84a authored by Koen Martens's avatar Koen Martens
Browse files

Frontend: add email to contacts

parent ba74122e
......@@ -41,6 +41,11 @@
<roles v-bind:contact="detail_record"></roles>
</b-col>
</b-row>
<b-row>
<b-col>
<email v-bind:contact="detail_record"></email>
</b-col>
</b-row>
</b-container>
</div>
</template>
......@@ -48,6 +53,7 @@
<script>
import axios from 'axios';
import Roles from './contacts/Roles.vue';
import Email from './contacts/Email.vue';
export default {
name: 'Contacts',
......@@ -55,6 +61,7 @@ export default {
},
components: {
Roles,
Email,
},
data: function() {
return {
......
<template>
<div>
<b-navbar type="dark" variant="info">
<b-navbar-brand>Email Addresses</b-navbar-brand>
<b-navbar-nav class="ml-auto">
<b-nav-item right>
<b-button @click="add_row" size="sm" v-if="contact.id"><b-icon-plus></b-icon-plus></b-button>
</b-nav-item>
</b-navbar-nav>
</b-navbar>
<b-table striped hover selectable select-mode="single" no-select-on-click
:items="email_addresses" id="email_table"
:busy="is_busy" primary-key="id" :fields="fields"
@row-clicked="row_clicked" ref="email_table">
<template #cell(type)="data">
<b-input v-model="data.item.type" v-bind:disabled="!data.rowSelected"
@update="row_changed(data.item)" debounce="1000">
</b-input>
</template>
<template #cell(address)="data">
<b-input v-model="data.item.address" v-bind:disabled="!data.rowSelected"
@update="row_changed(data.item)" debounce="1000">
</b-input>
</template>
<template #cell(date_from)="data">
<b-form-datepicker v-model="data.item.date_from" v-bind:disabled="!data.rowSelected"
:date-format-options="{ year: 'numeric', month: '2-digit', day: '2-digit' }"
@input="row_changed(data.item)">
</b-form-datepicker>
</template>
<template #cell(date_to)="data">
<b-form-datepicker v-model="data.item.date_to" v-bind:disabled="!data.rowSelected"
:date-format-options="{ year: 'numeric', month: '2-digit', day: '2-digit' }"
@input="row_changed(data.item)" >
</b-form-datepicker>
</template>
<template #cell(edit)="data">
<b-button v-if="!data.rowSelected" @click="row_clicked(data.item, data.index)" size="sm">
<b-icon-pencil-square></b-icon-pencil-square>
</b-button>
<b-button v-if="data.rowSelected" @click="save_row" size="sm">
<b-icon-check-square></b-icon-check-square>
</b-button>
</template>
<template #cell(delete)="data">
<b-button @click="delete_email_address(data)" size="sm">
<b-icon-trash></b-icon-trash>
</b-button>
</template>
</b-table>
<b-modal ref="confirm_delete_modal" title="Confirm deletion" v-bind:busy="delete_busy">
<p>Email address <span v-if="email_address_to_delete">'{{ email_address_to_delete.email_address.address }}' </span>
<span v-if="email_address_to_delete && email_address_to_delete.date_from"> from {{ email_address_to_delete.date_from }}</span>
<span v-if="email_address_to_delete && email_address_to_delete.date_to"> to {{ email_address_to_delete.date_to }}</span>.
</p>
<template #modal-footer="{ ok, cancel }">
<b-button size="sm" variant="danger" v-bind:disabled="delete_busy" @click="delete_confirmed">
Delete
</b-button>
<b-button size="sm" variant="success" v-bind:disabled="delete_busy" @click="cancel()">
Cancel
</b-button>
</template>
</b-modal>
</div>
</template>
<script>
import axios from 'axios';
export default {
name: 'Email',
props: {
'contact': Object,
},
data: function() {
return {
email_addresses: [],
fields: [
{ key: 'type'},
{ key: 'address'},
{ key: 'date_from', label: 'From'},
{ key: 'date_to', label: 'To'},
{ key: 'edit', label: ''},
{ key: 'delete', label: ''},
],
is_busy: false,
email_address_to_delete: null,
delete_busy: false,
}
},
created: function() {
if(this.contact.id !== null) {
this.load_email_addresses();
}
},
methods: {
'load_email_addresses': function() {
this.is_busy = true;
axios.get(this.$store.getters.api_url(['contacts', this.contact.id, 'email_addresses']), {
headers: {'Authorization': 'JWT ' + this.$store.state.jwt}
})
.then(response => {
this.email_addresses = response.data;
this.is_busy = false;
}).catch(error => {
console.log(error);
this.is_busy = false;
});
},
'row_clicked': function(record, index) {
this.$refs.email_table.selectRow(index);
},
'save_row': function() {
this.$refs.email_table.clearSelected();
},
'row_changed': function(item) {
let verb = axios.put;
let endpoint = ['email_addresses', item.id];
if(item.id == null) {
// new item, POST
verb = axios.post;
endpoint = ['contacts', this.contact.id, 'email_addresses'];
}
verb(this.$store.getters.api_url(endpoint), item, {
headers: {'Authorization': 'JWT ' + this.$store.state.jwt}
})
.then(response => {
item = response.data; // TODO: does not modify underlying object
})
.catch(error => {
console.log(error);
});
},
'add_row': function() {
this.email_addresses.unshift({
id: null,
type: 'work',
contact_id: this.contact.id,
date_from: null,
date_to: null,
email_address: {
'id': null,
'address': "",
},
});
const component = this;
setTimeout(function() {
// TODO: HACK! poor man's yield, but the table needs to re-render before being able to select
component.$refs.email_table.clearSelected();
component.$refs.email_table.selectRow(0);
}, 0);
},
'delete_email_address': function(data) {
this.email_address_to_delete = data.item;
this.$refs.confirm_delete_modal.show();
},
'delete_confirmed': function() {
this.delete_busy = true;
const component = this;
axios.delete(this.$store.getters.api_url(['contact_email_address', this.email_address_to_delete.id]), {
headers: {'Authorization': 'JWT ' + this.$store.state.jwt}
})
.then(function() {
component.$refs.confirm_delete_modal.hide();
component.delete_busy = false;
component.roles = component.roles.filter(x => x.id != component.email_address_to_delete.id);
component.role_to_delete = null;
})
.catch(error => {
component.$refs.confirm_delete_modal.hide();
component.delete_busy = false;
component.role_to_delete = null;
console.log(error);
});
},
}
}
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
</style>
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment