alerta_alerta-webui/src/components/HeartbeatList.vue

263 lines
6.1 KiB
Vue

<template>
<v-card>
<v-card-title class="title">
{{ $t('Heartbeats') }}
<v-spacer />
<v-btn-toggle
v-model="status"
class="transparent"
multiple
>
<v-btn
value="ok"
flat
>
<v-tooltip bottom>
<v-icon slot="activator">
check_circle
</v-icon>
<span>{{ $t('OK') }}</span>
</v-tooltip>
</v-btn>
<v-btn
value="slow"
flat
>
<v-tooltip bottom>
<v-icon slot="activator">
access_time
</v-icon>
<span>{{ $t('Slow') }}</span>
</v-tooltip>
</v-btn>
<v-btn
value="expired"
flat
>
<v-tooltip bottom>
<v-icon slot="activator">
timer_off
</v-icon>
<span>{{ $t('Expired') }}</span>
</v-tooltip>
</v-btn>
</v-btn-toggle>
<v-spacer />
<v-text-field
v-model="search"
append-icon="search"
:label="$t('Search')"
single-line
hide-details
/>
</v-card-title>
<v-data-table
:headers="computedHeaders"
:items="heartbeats"
:rows-per-page-items="rowsPerPageItems"
:pagination.sync="pagination"
class="px-2"
:search="search"
:loading="isLoading"
must-sort
sort-icon="arrow_drop_down"
>
<template
slot="items"
slot-scope="props"
>
<td>{{ props.item.origin }}</td>
<td
v-if="$config.customer_views"
>
{{ props.item.customer }}
</td>
<td>
<v-chip
v-for="tag in props.item.tags"
:key="tag"
label
small
>
<v-icon left>
label
</v-icon>{{ tag }}
</v-chip>
</td>
<td>
{{ props.item.attributes }}
</td>
<td>
<date-time
:value="props.item.createTime"
format="mediumDate"
/>
</td>
<td>
<date-time
:value="props.item.receiveTime"
format="mediumDate"
/>
</td>
<td>
{{ diffTime(props.item.createTime, props.item.receiveTime) }} ms
</td>
<td
class="text-xs-center text-no-wrap"
>
{{ timeoutLeft(props.item) | hhmmss }}
</td>
<td>
{{ props.item.receiveTime | timeago }}
</td>
<td>
<span :class="['label', 'label-' + props.item.status.toLowerCase()]">
{{ props.item.status | capitalize }}
</span>
</td>
<td class="text-no-wrap">
<v-btn
v-has-perms.disable="'write:heartbeats'"
icon
class="btn--plain mr-0"
@click="deleteItem(props.item)"
>
<v-icon
small
color="grey darken-3"
>
delete
</v-icon>
</v-btn>
</td>
</template>
<template slot="no-data">
<v-alert
:value="true"
color="error"
icon="warning"
>
{{ $t('NoDisplay') }}
</v-alert>
</template>
<v-alert
slot="no-results"
:value="true"
color="error"
icon="warning"
>
{{ $t('SearchNoResult1') }} "{{ search }}" {{ $t('SearchNoResult2') }}
</v-alert>
</v-data-table>
</v-card>
</template>
<script>
import DateTime from './lib/DateTime'
import moment from 'moment'
import i18n from '@/plugins/i18n'
export default {
components: {
DateTime
},
data: () => ({
descending: true,
page: 1,
rowsPerPageItems: [10, 20, 30, 40, 50],
pagination: {
sortBy: 'receiveTime',
descending: true,
rowsPerPage: 20
},
// totalItems: number,
status: ['ok', 'slow', 'expired'],
search: '',
headers: [
{ text: i18n.t('Origin'), value: 'origin' },
{ text: i18n.t('Customer'), value: 'customer' },
{ text: i18n.t('Tags'), value: 'tags' },
{ text: i18n.t('Attributes'), value: 'attributes' },
{ text: i18n.t('CreateTime'), value: 'createTime' },
{ text: i18n.t('ReceiveTime'), value: 'receiveTime' },
{ text: i18n.t('Latency'), value: 'latency' },
{ text: i18n.t('Timeout'), value: 'timeout' },
{ text: i18n.t('Since'), value: 'since' },
{ text: i18n.t('Status'), value: 'status' },
{ text: i18n.t('Actions'), value: 'name', sortable: false }
]
}),
computed: {
heartbeats() {
return this.$store.state.heartbeats.heartbeats.filter(hb => !this.status || this.status.includes(hb.status))
},
computedHeaders() {
return this.headers.filter(h => !this.$config.customer_views ? h.value != 'customer' : true)
},
isLoading() {
return this.$store.state.heartbeats.isLoading
},
refresh() {
return this.$store.state.refresh
}
},
watch: {
refresh(val) {
val || this.getHeartbeats()
}
},
created() {
this.getHeartbeats()
},
methods: {
timeoutLeft(item) {
let expireTime = moment(item.createTime).add(item.timeout, 'seconds')
return expireTime.isAfter() ? expireTime.diff(moment(), 'seconds') : moment.duration()
},
getHeartbeats() {
this.$store.dispatch('heartbeats/getHeartbeats')
},
deleteItem(item) {
confirm(i18n.t('ConfirmDelete')) &&
this.$store.dispatch('heartbeats/deleteHeartbeat', item.id)
},
diffTime(a, b) {
return new Date(b).getTime() - new Date(a).getTime()
}
}
}
</script>
<style>
.label {
font-size: 13px;
font-weight: bold;
line-height: 14px;
color: #ffffff;
text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);
white-space: nowrap;
vertical-align: baseline;
background-color: #999999;
}
.label {
padding: 1px 4px 2px;
-webkit-border-radius: 3px;
-moz-border-radius: 3px;
border-radius: 3px;
}
.label-expired {
background-color: #b94a48;
}
.label-slow {
background-color: #3a87ad;
}
.label-ok {
background-color: #468847;
}
</style>