From da34fc179c90b453c36d9a1cff2386427ed526c4 Mon Sep 17 00:00:00 2001 From: hunterlong Date: Thu, 20 Feb 2020 21:36:23 -0800 Subject: [PATCH] vue --- Dockerfile | 2 +- core/database.go | 10 ++ core/services.go | 19 ++- core/sparklines.go | 2 +- frontend/package.json | 1 + frontend/src/API.js | 5 + .../Dashboard/DashboardServices.vue | 89 ++------------ .../src/components/Dashboard/ServicesList.vue | 109 ++++++++++++++++++ frontend/src/components/Index/Group.vue | 10 +- .../components/Index/GroupServiceFailures.vue | 95 +++++++++++++++ .../src/components/Service/ServiceBlock.vue | 14 ++- .../src/components/Service/ServiceChart.vue | 20 +++- frontend/src/main.js | 2 + frontend/src/pages/Index.vue | 5 +- frontend/src/pages/Settings.vue | 2 +- frontend/src/store.js | 1 + handlers/routes.go | 1 + handlers/services.go | 28 ++++- types/gorm.go | 75 +++++++++++- 19 files changed, 387 insertions(+), 103 deletions(-) create mode 100644 frontend/src/components/Dashboard/ServicesList.vue create mode 100644 frontend/src/components/Index/GroupServiceFailures.vue diff --git a/Dockerfile b/Dockerfile index ad80b37f..939ce206 100644 --- a/Dockerfile +++ b/Dockerfile @@ -10,7 +10,7 @@ ADD Makefile go.mod /go/src/github.com/hunterlong/statping/ RUN go mod vendor && \ make dev-deps ADD . /go/src/github.com/hunterlong/statping -RUN cd frontend && yarn install +RUN cd frontend && yarn install --network-timeout 1000000 RUN make compile install # Statping :latest Docker Image diff --git a/core/database.go b/core/database.go index 9cee93bf..220e17cf 100644 --- a/core/database.go +++ b/core/database.go @@ -86,6 +86,16 @@ func (s *Service) HitsBetween(t1, t2 time.Time, group string, column string) typ } } +// FailuresBetween returns the gorm database query for a collection of service hits between a time range +func (s *Service) FailuresBetween(t1, t2 time.Time, group string, column string) types.Database { + selector := Dbtimestamp(group, column) + if CoreApp.Config.DbConn == "postgres" { + return Database(&Failure{}).Select(selector).Where("service = ? AND created_at BETWEEN ? AND ?", s.Id, t1.UTC().Format(types.TIME), t2.UTC().Format(types.TIME)) + } else { + return Database(&Failure{}).Select(selector).Where("service = ? AND created_at BETWEEN ? AND ?", s.Id, t1.UTC().Format(types.TIME_DAY), t2.UTC().Format(types.TIME_DAY)) + } +} + // CloseDB will close the database connection if available func CloseDB() { if DbSession != nil { diff --git a/core/services.go b/core/services.go index c7c4fab8..1b5109ca 100644 --- a/core/services.go +++ b/core/services.go @@ -272,7 +272,7 @@ type DateScanObj struct { } // GraphDataRaw will return all the hits between 2 times for a Service -func GraphDataRaw(service types.ServiceInterface, start, end time.Time, group string, column string) *DateScanObj { +func GraphHitsDataRaw(service types.ServiceInterface, start, end time.Time, group string, column string) *DateScanObj { model := service.(*Service).HitsBetween(start, end, group, column) model = model.Order("timeframe asc", false).Group("timeframe") outgoing, err := model.ToChart() @@ -282,6 +282,23 @@ func GraphDataRaw(service types.ServiceInterface, start, end time.Time, group st return &DateScanObj{outgoing} } +// GraphDataRaw will return all the hits between 2 times for a Service +func GraphFailuresDataRaw(service types.ServiceInterface, start, end time.Time, group string) []types.TimeValue { + srv := service.(*Service) + + query := Database(&types.Failure{}). + Where("service = ?", srv.Id). + Between(start, end). + MultipleSelects(types.SelectByTime(group), types.CountAmount()). + GroupByTimeframe().Debug() + + outgoing, err := query.ToTimeValue() + if err != nil { + log.Error(err) + } + return outgoing +} + // ToString will convert the DateScanObj into a JSON string for the charts to render func (d *DateScanObj) ToString() string { data, err := json.Marshal(d.Array) diff --git a/core/sparklines.go b/core/sparklines.go index 5bd1816c..163feb63 100644 --- a/core/sparklines.go +++ b/core/sparklines.go @@ -23,7 +23,7 @@ func (s *Service) SparklineHourResponse(hours int, method string) string { var arr []string end := time.Now().UTC() start := end.Add(time.Duration(-hours) * time.Hour) - obj := GraphDataRaw(s, start, end, "hour", method) + obj := GraphHitsDataRaw(s, start, end, "hour", method) for _, v := range obj.Array { arr = append(arr, utils.ToString(v.Value)) } diff --git a/frontend/package.json b/frontend/package.json index be8e7af4..14c3bd57 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -26,6 +26,7 @@ "vue-codemirror": "^4.0.6", "vue-flatpickr-component": "^8.1.5", "vue-moment": "^4.1.0", + "vue-observe-visibility": "^0.4.6", "vue-router": "~3.0", "vuedraggable": "^2.23.2", "vuex": "^3.1.2" diff --git a/frontend/src/API.js b/frontend/src/API.js index 2a50ca13..45124634 100644 --- a/frontend/src/API.js +++ b/frontend/src/API.js @@ -40,6 +40,10 @@ class Api { return axios.get('/api/services/' + id + '/data?start=' + start + '&end=' + end + '&group=' + group).then(response => (response.data)) } + async service_failures_data(id, start, end, group) { + return axios.get('/api/services/' + id + '/failure_data?start=' + start + '&end=' + end + '&group=' + group).then(response => (response.data)) + } + async service_heatmap(id, start, end, group) { return axios.get('/api/services/' + id + '/heatmap').then(response => (response.data)) } @@ -61,6 +65,7 @@ class Api { } async groups_reorder(data) { + window.console.log('/api/reorder/groups', data) return axios.post('/api/reorder/groups', data).then(response => (response.data)) } diff --git a/frontend/src/components/Dashboard/DashboardServices.vue b/frontend/src/components/Dashboard/DashboardServices.vue index 4e1ca18f..74f1db4e 100644 --- a/frontend/src/components/Dashboard/DashboardServices.vue +++ b/frontend/src/components/Dashboard/DashboardServices.vue @@ -3,57 +3,11 @@

Services - Create + Create

- - - - - - - - - - - - - - - - - - - -
NameStatusVisibilityGroup
- - - {{service.name}} - - - {{service.online ? "ONLINE" : "OFFLINE"}} - - - - - {{service.public ? "PUBLIC" : "PRIVATE"}} - - -
{{serviceGroup(service)}}
-
-
- - Edit - - - View - - - - -
-
+
@@ -71,8 +25,10 @@ - - {{group.name}} + + + {{group.name}} + {{$store.getters.servicesInGroup(group.id).length}} PUBLIC @@ -102,10 +58,12 @@ import Api from "../../API"; import ToggleSwitch from "../../forms/ToggleSwitch"; import draggable from 'vuedraggable' + import ServicesList from './ServicesList'; export default { name: 'DashboardServices', components: { + ServicesList, ToggleSwitch, FormGroup, draggable @@ -117,23 +75,9 @@ } }, computed: { - servicesList: { - get() { - return this.$store.state.servicesInOrder - }, - async set(value) { - let data = []; - value.forEach((s, k) => { - data.push({service: s.id, order: k + 1}) - }); - await Api.services_reorder(data) - const services = await Api.services() - this.$store.commit('setServices', services) - } - }, groupsList: { get() { - return this.$store.state.groupsInOrder + return this.$store.getters.groupsCleanInOrder }, async set(value) { let data = []; @@ -165,13 +109,6 @@ window.console.log("saving..."); window.console.log(this.myViews.array()); // this.myViews.array is not a function }, - serviceGroup(s) { - let group = this.$store.getters.groupById(s.group_id) - if (group) { - return group.name - } - return "" - }, async deleteGroup(g) { let c = confirm(`Are you sure you want to delete '${g.name}'?`) if (c) { @@ -179,14 +116,6 @@ const groups = await Api.groups() this.$store.commit('setGroups', groups) } - }, - async deleteService(s) { - let c = confirm(`Are you sure you want to delete '${s.name}'?`) - if (c) { - await Api.service_delete(s.id) - const services = await Api.services() - this.$store.commit('setServices', services) - } } } } diff --git a/frontend/src/components/Dashboard/ServicesList.vue b/frontend/src/components/Dashboard/ServicesList.vue new file mode 100644 index 00000000..20ee1cee --- /dev/null +++ b/frontend/src/components/Dashboard/ServicesList.vue @@ -0,0 +1,109 @@ + + + + + + diff --git a/frontend/src/components/Index/Group.vue b/frontend/src/components/Index/Group.vue index 098b8de4..1e98769f 100644 --- a/frontend/src/components/Index/Group.vue +++ b/frontend/src/components/Index/Group.vue @@ -6,6 +6,8 @@ {{service.name}} {{service.online ? "ONLINE" : "OFFLINE"}} + + @@ -13,20 +15,18 @@ diff --git a/frontend/src/components/Index/GroupServiceFailures.vue b/frontend/src/components/Index/GroupServiceFailures.vue new file mode 100644 index 00000000..bf5385ce --- /dev/null +++ b/frontend/src/components/Index/GroupServiceFailures.vue @@ -0,0 +1,95 @@ + + + + + + diff --git a/frontend/src/components/Service/ServiceBlock.vue b/frontend/src/components/Service/ServiceBlock.vue index 43d337ba..b034fe36 100644 --- a/frontend/src/components/Service/ServiceBlock.vue +++ b/frontend/src/components/Service/ServiceBlock.vue @@ -13,8 +13,8 @@ -
- +
+
@@ -46,6 +46,11 @@ export default { required: true }, }, + data() { + return { + visible: false, + } + }, methods: { smallText(s) { if (s.online) { @@ -53,6 +58,11 @@ export default { } else { return `Offline, last error: ${s.last_failure.issue} ${this.ago(this.parseTime(s.last_failure.created_at))}` } + }, + visibleChart(isVisible, entry) { + if (isVisible && !this.visible) { + this.visible = true + } } } } diff --git a/frontend/src/components/Service/ServiceChart.vue b/frontend/src/components/Service/ServiceChart.vue index ec483d31..eb550181 100644 --- a/frontend/src/components/Service/ServiceChart.vue +++ b/frontend/src/components/Service/ServiceChart.vue @@ -1,5 +1,5 @@ -