notweb/web/index.html
2020-05-03 16:51:20 +02:00

162 lines
No EOL
6.5 KiB
HTML

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="https://unpkg.com/buefy/dist/buefy.min.css">
<style>
.maillist .tags {
display: inline;
}
</style>
</head>
<body>
<section class="section">
<div class="">
<div id="app" class="columns">
<div class="column is-two-fifths">
<div class="box">
<b-taginput icon="magnify" placeholder="Search..." expanded v-model="mailSearch" autocomplete
allow-new :data="mailSearchAutocomplete" @typing="getFilteredMailAddrs" @input="loadMails">
</b-taginput>
<b-table :data="mailTable" :loading="mailLoading" narrowed :row-class="() => 'maillist'"
paginated backend-pagination :total="mailTotal" :per-page="mailLimit"
@page-change="mailPageChange" @select="mailSelect">
<template slot-scope="props">
<b-table-column field="date" label="Datum">
{{ props.row.date}}
</b-table-column>
<b-table-column field="subject" label="Subject">
<b-taglist attached>
<b-tag v-for="tag in props.row.tags" type="is-info">
{{ tag }}
</b-tag>
<b-tag type="is-success">{{ props.row.count }}</b-tag>
</b-taglist>
{{ props.row.subject}}
</b-table-column>
</template>
</b-table>
</div>
</div>
<div class="column">
<div class="box" v-for="message_id in openThread.message_ids" @key="message_id">
<h2>{{openThread.subject}}</h2>
<b-taglist attached>
<b-tag v-for="tag in openThreadMessages[message_id].tags" type="is-info">
{{ tag }}
</b-tag>
</b-taglist>
<hr>
<div v-html="openThreadMessages[message_id].body"></div>
</div>
</div>
</div>
</div>
<script src="https://unpkg.com/vue"></script>
<script src="https://unpkg.com/buefy/dist/buefy.min.js"></script>
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<script>
new Vue({
el: '#app',
data: {
mailTable: [],
mailSearch: ['tag:inbox'],
mailLoading: false,
mailStart: 0,
mailLimit: 30,
mailTotal: 0,
mailRowContent: {},
mailAddrs: [],
mailTags: [],
mailBody: '',
mailSearchAutocomplete: [],
searchTimeout: null,
openThread: {},
openThreadMessages: [],
},
filters: {
truncate(value) {
if (value.length > 11) {
value = value.substring(0, 10) + '…';
}
return value;
},
},
methods: {
loadMails() {
this.mailLoading = true;
search = this.mailSearch.join(' ');
axios.get(`/search/${search}/${this.mailStart}/${this.mailLimit}`)
.then(({ data }) => {
this.mailTable = data.threads;
this.mailTotal = data.count;
this.mailLoading = false;
})
.catch(({ request }) => {
this.mailTable = [];
this.mailTotal = 0;
this.mailLoading = false;
})
},
getFilteredMailAddrs(text) {
kind = text.split(':', 1);
text = text.substr(text.indexOf(':') + 1);
axios.get(`/autocomplete/${kind}/${text}`)
.then(({ data }) => {
this.mailSearchAutocomplete = data.results.filter((option) => {
return option.indexOf(text) >= 0;
});
})
},
mailPageChange(page) {
this.mailStart = (page - 1) * this.mailLimit;
this.loadMails();
},
doMailSearch(search) {
this.mailSearch = search;
this.loadMails();
},
debounceSearch(search) {
if (this.searchTimeout) {
clearTimeout(this.searchTimeout);
}
this.searchTimeout = setTimeout(() => {
this.doMailSearch(search);
}, 100);
},
mailSelect(row) {
axios.get(`/thread/${row.thread_id}`)
.then(({ data }) => {
this.openThread = data;
this.openThreadMessages = {};
data.message_ids.forEach((messageId) => {
axios.get(`/message/${encodeURIComponent(messageId)}`)
.then((data) => { this.$set(this.openThreadMessages, messageId, data.data) })
})
});
},
},
mounted() {
this.loadMails();
}
})
</script>
</div>
</section>
</body>
</html>