src/views/Timeline.vue
<template lang="pug">
div
h2 Timeline
input-timeinterval(v-model="daterange", :defaultDuration="timeintervalDefaultDuration", :maxDuration="maxDuration").mb-2
// blocks
div.d-inline-block.border.rounded.p-2.mr-2
| Events shown: {{ num_events }}
details.d-inline-block.bg-light.small.border.rounded.mr-2.px-2
summary.p-2
b Filters
div.p-2.bg-light
table
tr
th.pt-2.pr-3
label Host:
td
select(v-model="filter_hostname")
option(:value='null') All
option(v-for="host in hosts", :value="host") {{ host }}
tr
th.pt-2.pr-3
label Client:
td
select(v-model="filter_client")
option(:value='null') All
option(v-for="client in clients", :value="client") {{ client }}
div(style="float: right; color: #999").d-inline-block.pt-3
| Drag to pan and scroll to zoom
div(v-if="buckets !== null")
div(style="clear: both")
vis-timeline(:buckets="buckets", :showRowLabels='true', :queriedInterval="daterange")
aw-devonly(reason="Not ready for production, still experimenting")
aw-calendar(:buckets="buckets")
div(v-else)
h1.aw-loading Loading...
</template>
<script lang="ts">
import _ from 'lodash';
import { useSettingsStore } from '~/stores/settings';
import { useBucketsStore } from '~/stores/buckets';
export default {
name: 'Timeline',
data() {
return {
all_buckets: null,
hosts: null,
buckets: null,
clients: null,
daterange: null,
maxDuration: 31 * 24 * 60 * 60,
filter_hostname: null,
filter_client: null,
};
},
computed: {
timeintervalDefaultDuration() {
const settingsStore = useSettingsStore();
return Number(settingsStore.durationDefault);
},
num_events() {
return _.sumBy(this.buckets, 'events.length');
},
},
watch: {
daterange() {
this.getBuckets();
},
filter_hostname() {
this.getBuckets();
},
filter_client() {
this.getBuckets();
},
},
methods: {
getBuckets: async function () {
if (this.daterange == null) return;
this.all_buckets = Object.freeze(
await useBucketsStore().getBucketsWithEvents({
start: this.daterange[0].format(),
end: this.daterange[1].format(),
})
);
this.hosts = this.all_buckets
.map(a => a.hostname)
.filter((value, index, array) => array.indexOf(value) === index);
this.clients = this.all_buckets
.map(a => a.client)
.filter((value, index, array) => array.indexOf(value) === index);
let buckets = this.all_buckets;
if (this.filter_hostname) {
buckets = _.filter(buckets, b => b.hostname == this.filter_hostname);
}
if (this.filter_client) {
buckets = _.filter(buckets, b => b.client == this.filter_client);
}
this.buckets = buckets;
},
},
};
</script>
<style scoped>
details {
position: relative;
}
details[open] summary ~ * {
visibility: visible;
position: absolute;
border: 1px solid #ddd;
border-radius: 5px;
left: 0;
top: 2.7em;
background: white;
z-index: 100;
}
</style>