delete checkins when service is deleted, search in logs on UI, added UI alerts when tables are empty

pull/760/head
hunterlong 2020-07-22 13:15:35 -07:00
parent d16c2aad72
commit 4728a82006
8 changed files with 91 additions and 18 deletions

View File

@ -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

View File

@ -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>

View File

@ -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)

View File

@ -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>

View File

@ -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>

View File

@ -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))
}
}
}

View File

@ -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) {

View File

@ -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()