mirror of https://github.com/statping/statping
delete checkins when service is deleted, search in logs on UI, added UI alerts when tables are empty
parent
d16c2aad72
commit
4728a82006
|
@ -1,4 +1,4 @@
|
|||
# 0.90.61 (07-19-2020)
|
||||
# 0.90.61 (07-22-2020)
|
||||
- Modified sass layouts, organized and split up sections
|
||||
- Modified Checkins to seconds rather than milliseconds (for cronjob)
|
||||
- Modified Service View page to show data inside cards
|
||||
|
@ -10,6 +10,7 @@
|
|||
- Added additional testing
|
||||
- Modified node version from 10.x to 12.18.2
|
||||
- Modified Notifier's struct values to be NullString and NullInt to allow empty values
|
||||
- Added Search ability to Logs in UI
|
||||
|
||||
# 0.90.60 (07-15-2020)
|
||||
- Added LETSENCRYPT_ENABLE (boolean) env to enable/disable letsencrypt SSL
|
||||
|
|
|
@ -16,6 +16,15 @@
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-12" v-if="services.length === 0">
|
||||
<div class="alert alert-dark d-block">
|
||||
You currently don't have any services!
|
||||
<router-link v-if="$store.state.admin" to="/dashboard/create_service" class="btn btn-sm btn-success float-right">
|
||||
<font-awesome-icon icon="plus"/> Create
|
||||
</router-link>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div v-for="(service, index) in services" class="service_block" v-bind:key="index">
|
||||
<ServiceInfo :service=service />
|
||||
</div>
|
||||
|
|
|
@ -3,7 +3,14 @@
|
|||
<div class="card contain-card mb-4">
|
||||
<div class="card-header">{{ $t('top_nav.announcements') }}</div>
|
||||
<div class="card-body pt-0">
|
||||
<table class="table table-striped">
|
||||
|
||||
<div v-if="messages.length === 0">
|
||||
<div class="alert alert-dark d-block mt-3 mb-0">
|
||||
You currently don't have any Announcements! Create one using the form below.
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<table v-else class="table table-striped">
|
||||
<thead>
|
||||
<tr>
|
||||
<th scope="col">{{ $t('dashboard.title') }}</th>
|
||||
|
@ -13,7 +20,7 @@
|
|||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr v-for="message in $store.getters.messages" v-bind:key="message.id">
|
||||
<tr v-for="message in messages" v-bind:key="message.id">
|
||||
<td>{{message.title}}</td>
|
||||
<td class="d-none d-md-table-cell">
|
||||
<router-link :to="serviceLink(service(message.service))">{{serviceName(service(message.service))}}</router-link>
|
||||
|
@ -51,6 +58,11 @@
|
|||
message: {}
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
messages() {
|
||||
return this.$store.getters.messages
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
goto(to) {
|
||||
this.$router.push(to)
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<div class="col-12">
|
||||
<div class="card contain-card mb-4">
|
||||
<div class="card-header">{{ $t('top_nav.services') }}
|
||||
<router-link v-if="$store.state.admin" to="/dashboard/create_service" class="btn btn-sm btn-outline-success float-right">
|
||||
<router-link v-if="$store.state.admin" to="/dashboard/create_service" class="btn btn-sm btn-success float-right">
|
||||
<font-awesome-icon icon="plus"/> Create
|
||||
</router-link>
|
||||
</div>
|
||||
|
@ -14,7 +14,14 @@
|
|||
<div class="card contain-card mb-4">
|
||||
<div class="card-header">{{ $t('top_nav.groups') }}</div>
|
||||
<div class="card-body pt-0">
|
||||
<table class="table">
|
||||
|
||||
<div v-if="groupsList.length === 0">
|
||||
<div class="alert alert-dark d-block mt-3 mb-0">
|
||||
You currently don't have any groups! Create one using the form below.
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<table v-else class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th scope="col">{{ $t('dashboard.name') }}</th>
|
||||
|
|
|
@ -1,5 +1,11 @@
|
|||
<template>
|
||||
<table class="table">
|
||||
<div>
|
||||
<div v-if="servicesList.length === 0">
|
||||
<div class="alert alert-dark d-block mt-3 mb-0">
|
||||
You currently don't have any services!
|
||||
</div>
|
||||
</div>
|
||||
<table v-else class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th scope="col">Name</th>
|
||||
|
@ -42,6 +48,7 @@
|
|||
</tr>
|
||||
</draggable>
|
||||
</table>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
|
|
@ -1,9 +1,25 @@
|
|||
<template>
|
||||
<div class="col-12 p-4">
|
||||
<p v-if="logs.length === 0" class="text-monospace sm">
|
||||
Loading Logs...
|
||||
</p>
|
||||
<p v-for="(log, index) in logs" class="text-monospace sm">{{log}}</p>
|
||||
<div class="col-12">
|
||||
<div class="card contain-card mb-4">
|
||||
<div class="card-header">
|
||||
Logs
|
||||
<div class="input-group input-group-sm float-right col-6">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text" id="inputGroup-sizing-sm">Search</span>
|
||||
</div>
|
||||
<input v-model="search" type="text" class="form-control">
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<p v-if="logs.length === 0" class="text-monospace sm">
|
||||
Loading Logs...
|
||||
</p>
|
||||
<div v-for="(log, index) in logs">
|
||||
<span class="badge badge-secondary small mr-2">{{log.time}}</span>
|
||||
<span class="text-monospace small">{{log.message}}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
@ -14,40 +30,58 @@ export default {
|
|||
name: 'Logs',
|
||||
data() {
|
||||
return {
|
||||
logs: [],
|
||||
logs_record: [],
|
||||
last: "",
|
||||
search: "",
|
||||
t: null
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
logs() {
|
||||
if (this.search) {
|
||||
return this.logs_record.filter(o => o.message.includes(this.search));
|
||||
} else {
|
||||
return this.logs_record
|
||||
}
|
||||
}
|
||||
},
|
||||
async created() {
|
||||
await this.getLogs()
|
||||
if (!this.t) {
|
||||
this.t = setInterval(async () => {
|
||||
await this.lastLog()
|
||||
}, 650)
|
||||
}, 1000)
|
||||
}
|
||||
},
|
||||
beforeDestroy() {
|
||||
clearInterval(this.t)
|
||||
},
|
||||
methods: {
|
||||
parseLog(data) {
|
||||
const ts = data.match(/[0-9]{4}-(0[1-9]|1[0-2])-(0[1-9]|[1-2][0-9]|3[0-1]) (2[0-3]|[01][0-9]):[0-5][0-9]:[0-5][0-9]/gm)
|
||||
return {
|
||||
time: ts[0],
|
||||
message: data.split(ts+": ")[1]
|
||||
}
|
||||
},
|
||||
cleanLog(l) {
|
||||
const splitLog = l.split(": ")
|
||||
const last = splitLog.slice(1);
|
||||
return last.join(": ")
|
||||
},
|
||||
async getLogs() {
|
||||
const logs = await Api.logs()
|
||||
const l = logs.reverse()
|
||||
const l = await Api.logs()
|
||||
l.forEach((d) => {
|
||||
this.logs_record.push(this.parseLog(d))
|
||||
})
|
||||
this.last = this.cleanLog(l[l.length - 1])
|
||||
this.logs = l
|
||||
},
|
||||
async lastLog() {
|
||||
const log = await Api.logs_last()
|
||||
const cleanLast = this.cleanLog(log)
|
||||
if (this.last !== cleanLast) {
|
||||
this.last = cleanLast
|
||||
this.logs.reverse().push(log)
|
||||
this.logs_record.unshift(this.parseLog(log))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -47,7 +47,7 @@ func TestPushoverNotifier(t *testing.T) {
|
|||
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, "Hunter Long", Pushover.Author)
|
||||
assert.Equal(t, PUSHOVER_TOKEN, Pushover.ApiKey)
|
||||
assert.Equal(t, PUSHOVER_TOKEN, Pushover.ApiKey.String)
|
||||
})
|
||||
|
||||
t.Run("Pushover Within Limits", func(t *testing.T) {
|
||||
|
|
|
@ -99,6 +99,9 @@ func (s *Service) Delete() error {
|
|||
if err := s.DeleteHits(); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := s.DeleteCheckins(); err != nil {
|
||||
return err
|
||||
}
|
||||
delete(allServices, s.Id)
|
||||
q := db.Model(&Service{}).Delete(s)
|
||||
return q.Error()
|
||||
|
|
Loading…
Reference in New Issue