sermoni

"Service monitor" / cronjob status service
Log | Files | Refs

commit 8d4945b5fa3063cd3c629a2355be9ffa7142ac0b
parent 5ae82004b2571537600fb288d143099d4f737893
Author: Vetle Haflan <vetle.haflan@luxsave.com>
Date:   Sat, 23 May 2020 15:53:41 +0200

Implement prettier time picker

Closes #7

Diffstat:
Minternal/services/services.go | 8++++----
Mui/src/Services.vue | 104++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++----------------
Aui/src/TimePicker.vue | 55+++++++++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 143 insertions(+), 24 deletions(-)

diff --git a/internal/services/services.go b/internal/services/services.go @@ -45,8 +45,8 @@ func GetByID(id uint64) *Service { } // GetAll returns all services in the database (TODO) -func GetAll() ([]*Service) { - services := []*Service{} +func GetAll() []*Service { + services := []*Service{} db := database.GetDB() db.View(func(tx *bbolt.Tx) error { b := tx.Bucket(database.BucketKeyServices) @@ -58,9 +58,9 @@ func GetAll() ([]*Service) { log.Panic("The service-tokens bucket does not exist") } - // Go through all k-v pairs in the service *tokens* bucket, in order to get service bucket IDs + // Go through all k-v pairs in the service *tokens* bucket, in order to get service bucket IDs. // Use the ID to get the service bucket and create service fromBucket, then set the service token - // using the key from the stb + // using the key from the stb. The returned list of services will be sorted by *token*. return stb.ForEach(func(token, id []byte) error { sb := b.Bucket(id) service := new(Service) diff --git a/ui/src/Services.vue b/ui/src/Services.vue @@ -1,22 +1,29 @@ <template> <div class="services-wrapper"> - <div v-for="service in services"> - {{ service.id }} : - <input :type="showPasswords ? 'text' : 'password'" :value="service.token"> - <input type="text" :value="service.name"> - <input type="text" :value="service.description"> - <input type="number" :value="service.period"> - <input type="number" :value="service.maxevents"> + <div class="service" v-for="service in services" :key="service.id"> + {{ service.id }} : <br/> + + <span>Token</span> + <input :type="showPasswords ? 'text' : 'password'" :value="service.token"/> <br/> + + <span>Name</span> + <input type="text" :value="service.name"/> <br/> + + <span>Description</span> + <input type="text" :value="service.description"/> <br/> + + <span>Max number of events</span> + <input type="number" :value="service.maxevents"/> <br/> + + <span>Expectation period</span> + <time-picker :value="service.period"/> <br/> </div> - <input :type="showPasswords ? 'text' : 'password'" v-model="newService.token" placeholder="Token"> - <input type="text" v-model="newService.name" placeholder="Name"> - <input type="text" v-model="newService.description" - placeholder="Description"> - <input type="number" v-model.number="newService.period" - placeholder="Expectation Period"> - <input type="number" v-model.number="newService.maxevents" - placeholder="Max number of events"> + <input :type="showPasswords ? 'text' : 'password'" v-model="newService.token" placeholder="Token"> <br/> + <input type="text" v-model="newService.name" placeholder="Name"> <br/> + <input type="text" v-model="newService.description" placeholder="Description"> <br/> + <input type="number" v-model.number="newService.maxevents" placeholder="Max number of events"> <br/> + <time-picker v-model="newService.period" placeholder="Expectation Period"/> <br/> <button @click="addService">Add service</button> </div> @@ -24,8 +31,10 @@ <script> import api from "./requests.js"; + import TimePicker from "./TimePicker.vue"; export default { name: "Services", + components: {TimePicker}, data() { return { services: [], @@ -33,7 +42,7 @@ token: "", name: "", description: "", - period: 0, + period: {"number": 0, "scalar": 0}, maxevents: 0 }, showPasswords: true @@ -41,24 +50,55 @@ }, methods: { addService() { - api.postService(this.newService, + // Make unix milli time formatted period before sending + const formattedService = { + ...this.newService, + }; + formattedService.period = this.newService.period.scalar * this.newService.period.number; + console.log(formattedService); + api.postService(formattedService, success => { this.services.push(this.newService); this.newService = { token: "", name: "", description: "", - period: 0, maxevents: 0 + period: {"number": 0, "scalar": 0}, maxevents: 0 }; }, error => { this.$emit("error"); } ); + }, + getExpectations(unixMilliTime) { + const units = [ + { "unit": "weeks", "scalar": 604800000 }, + { "unit": "days", "scalar": 86400000 }, + { "unit": "hours", "scalar": 3600000 }, + { "unit": "minutes", "scalar": 60000 }, + { "unit": "seconds", "scalar": 1000 }, + { "unit": "none", "scalar": 0 } + ]; + if (unixMilliTime === 0) { + return { "number": 0, "scalar": 0 }; + } + for (let i = 0; i < units.length; i++) { + let u = units[i]; + if (unixMilliTime % u.scalar === 0) { + return { + "scalar": u.scalar, + "number": unixMilliTime / u.scalar + }; + } + } } }, mounted() { api.getServices( services => { - this.services = services; + this.services = services.map(s => { + s.period = this.getExpectations(s.period); + return s; + }); }, error => { console.log(error); @@ -69,5 +109,29 @@ } </script> -<style scoped> +<style > +span { + font-weight: bold; +} +input { + border-width: 0 0 1px; + border-color: #bbf; + background-color: inherit; + outline-width: 0; + flex: 1; + margin-bottom: 3px; + width: 100%; +} +input:focus { + outline-width: 0; +} +input::placeholder { + color: #bbf; +} +div .service { + border: 1px solid blueviolet; + border-radius: 3px; + margin-bottom: 1em; + padding: 1em; +} </style> diff --git a/ui/src/TimePicker.vue b/ui/src/TimePicker.vue @@ -0,0 +1,54 @@ +<template> + <div> + <input type="number" @input="update('number', $event)" :value="number"/> + <select @input="update('scalar', $event)" :value="scalar"> + <option v-for="u in units" + :key="u.unit" + :value="u.scalar" + :selected="scalar === u.scalar"> + {{u.unit}} + </option> + </select> + </div> +</template> + +<script> + export default { + name: "TimePicker", + props: { + value: Object + }, + data() { + return { + number: this.value.number, + scalar: this.value.scalar, + units: [ + { "unit": "weeks", "scalar": 604800000 }, + { "unit": "days", "scalar": 86400000 }, + { "unit": "hours", "scalar": 3600000 }, + { "unit": "minutes", "scalar": 60000 }, + { "unit": "seconds", "scalar": 1000 }, + { "unit": "none", "scalar": 0 }, + ] + } + }, + watch: { + value: { + immediate: true, + handler(val) { + this.number = val.number; + this.scalar = val.scalar; + } + } + }, + methods: { + update(prop, e) { + console.log(e) + const newValue = this.value; + newValue[prop] = e.target.value; + this.$emit("input", newValue); + }, + + } + } +</script>+ \ No newline at end of file