diff --git a/Gruntfile.js b/Gruntfile.js index be0ed86..c3bffb7 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -44,7 +44,7 @@ module.exports = function(grunt) { } }, js: { - files: ['assets/scripts/**/*.js'], + files: ['assets/scripts/**/*.coffee'], tasks: ['coffee'], options: { atBegin: true, diff --git a/Makefile b/Makefile index fee0341..519740f 100644 --- a/Makefile +++ b/Makefile @@ -6,6 +6,16 @@ VERSION=`git describe --tags` build: @go build -o $(NAME) -ldflags "-X git.metaunix.net/bitgoblin/blt/app.AppVersion=$(VERSION)" +.PHONY: grunt +## grunt: Compile frontend assets. +grunt: + @npm run grunt + +.PHONY: grunt-watch +## grunt-watch: Compile frontend assets while watching for changes. +grunt-watch: + @npm run grunt watch + .PHONY: run ## run: Build and Run in development mode. run: build diff --git a/assets/scripts/kebos.coffee b/assets/scripts/kebos.coffee index 53b9de2..7ed63b8 100644 --- a/assets/scripts/kebos.coffee +++ b/assets/scripts/kebos.coffee @@ -1,2 +1,7 @@ +root = if typeof window isnt 'undefined' then window else global + +root.roundDecimal = (value) -> + return Math.round(value * 100) / 100 + $ -> console.log('DOM is ready.') diff --git a/assets/scripts/test.coffee b/assets/scripts/test.coffee new file mode 100644 index 0000000..ec6e1b2 --- /dev/null +++ b/assets/scripts/test.coffee @@ -0,0 +1,62 @@ +testId = $('#results-table').data('test-id') + +$ -> + $('#result-form').on 'submit', (e) -> + e.preventDefault() + + form = $(this) + formData = $(this).serialize() + benchmarkId = $(this).find('[name="result_benchmark"]').val() + + $.post '/api/v1/result/add', formData, (response) -> + if response == 'success' + fetchTestBenchmarkResults(testId, benchmarkId) + form[0].reset() + +fetchTestBenchmarkResults = (testId, benchmarkId) -> + try + benchmarkSearchParams = new URLSearchParams + benchmark_id: benchmarkId + benchmarkRes = await fetch("/api/v1/benchmark/details?#{benchmarkSearchParams}") + benchmarkData = await benchmarkRes.json() + + resultSearchParams = new URLSearchParams + test_id: testId + benchmark_id: benchmarkId + resultRes = await fetch("/api/v1/result/list?#{resultSearchParams}") + resultData = await resultRes.json() + + avg_total = 0 + min_total = 0 + max_total = 0 + + for result in resultData + avg_total += result.AverageScore + min_total += result.MinimumScore if result.MinimumScore + max_total += result.MaximumScore if result.MaximumScore + + tableRow = $("#results-table tr[data-benchmark-id=#{benchmarkId}]") + tableRow.empty() + + tableRow.append('' + benchmarkData.Name + '') + tableRow.append('' + benchmarkData.ScoringType + '') + tableRow.append('' + resultData.length + '') + + if resultData.length != 0 + tableRow.append('' + roundDecimal(avg_total / resultData.length) + '') + else + tableRow.append('N/a') + + if min_total != 0 + tableRow.append('' + roundDecimal(min_total / resultData.length) + '') + tableRow.append('' + roundDecimal(max_total / resultData.length) + '') + else + tableRow.append('N/a') + tableRow.append('N/a') + catch error + console.error 'An error occurred while fetching benchmark results.', error + +$('#results-table tbody tr').each (index, tr) -> + benchmarkId = $(tr).data('benchmark-id') + console.log("Fetching results for benchmark id: " + benchmarkId) + fetchTestBenchmarkResults(testId, benchmarkId) diff --git a/main.go b/main.go index c4ede23..2e71429 100644 --- a/main.go +++ b/main.go @@ -21,6 +21,9 @@ func main() { // initialize database models.Open() + // initialize base renderer + f.Use(flamego.Renderer()) + // initialize templating engine f.Use(template.Templater()) diff --git a/models/hardware.go b/models/hardware.go index 7894f39..a0381c1 100644 --- a/models/hardware.go +++ b/models/hardware.go @@ -11,7 +11,4 @@ type Hardware struct { // has many tests Tests []Test - - // has many results - Results []Result } diff --git a/models/result.go b/models/result.go index a8765ac..63e44dd 100644 --- a/models/result.go +++ b/models/result.go @@ -10,10 +10,6 @@ type Result struct { MinimumScore float32 MaximumScore float32 - // belongs to Hardware - HardwareID int - Hardware Hardware - // belongs to Benchmark BenchmarkID int Benchmark Benchmark diff --git a/templates/test/view.tmpl b/templates/test/view.tmpl index cd09e8f..055fe6f 100644 --- a/templates/test/view.tmpl +++ b/templates/test/view.tmpl @@ -3,7 +3,7 @@

{{ .test.Name }}

-

link to hardware tested.

+

Hardware tested: {{ .test.Hardware.Name }}

{{ .test.Description }}

@@ -19,7 +19,7 @@

Add new result:

-
+
-

-

Latest Benchmark Results:

+

Benchmark Results:

- {{ $length := len .test.Results }} {{ if eq $length 0 }} + {{ $length := len .test.Benchmarks }} {{ if eq $length 0 }}

There are currently no benchmarks recorded in this test.

{{ else }} - +
+ + - {{ range $res := .test.Results }} - - - - - - + {{ range $benchmark := .test.Benchmarks }} + {{ end }}
BenchmarkScoring Type# of Results Average Minimum Maximum
{{ $res.Benchmark.Name }}{{ $res.AverageScore }}{{ if eq $res.MinimumScore 0.0 }}N/a{{ else }}{{ $res.MinimumScore }}{{ end }}{{ if eq $res.MaximumScore 0.0 }}N/a{{ else }}{{ $res.MaximumScore }}{{ end }}
@@ -96,4 +92,6 @@

Back

+ + {{ template "footer" . }} diff --git a/web/forms/result.go b/web/forms/result.go index a9368a6..45ed3ec 100644 --- a/web/forms/result.go +++ b/web/forms/result.go @@ -2,7 +2,6 @@ package forms type ResultForm struct { Test int `form:"result_test" validate:"required"` - Hardware int `form:"result_hardware" validate:"required"` Benchmark int `form:"result_benchmark" validate:"required"` AverageScore float32 `form:"result_avg" validate:"required"` MinimumScore float32 `form:"result_min"` diff --git a/web/routes.go b/web/routes.go index 1e1b3ad..203d549 100644 --- a/web/routes.go +++ b/web/routes.go @@ -58,4 +58,18 @@ func RegisterRoutes(f *flamego.Flame) { f.Group("/result", func() { f.Post("/add", binding.Form(forms.ResultForm{}), routes.ResultPostCreate) }) + + // API v1 routes + f.Group("/api", func () { + f.Group("/v1", func() { + f.Group("/benchmark", func() { + f.Get("/details", routes.ApiV1BenchmarkDetails) + }) + + f.Group("/result", func() { + f.Post("/add", binding.Form(forms.ResultForm{}), routes.ApiV1ResultAdd) + f.Get("/list", routes.ApiV1ResultList) + }) + }) + }) } diff --git a/web/routes/api_v1.go b/web/routes/api_v1.go new file mode 100644 index 0000000..6fe157a --- /dev/null +++ b/web/routes/api_v1.go @@ -0,0 +1,62 @@ +package routes + +import ( + "log" + + "github.com/flamego/binding" + "github.com/flamego/flamego" + "github.com/flamego/validator" + + "git.metaunix.net/bitgoblin/blt/models" + "git.metaunix.net/bitgoblin/blt/web/forms" +) + +func ApiV1BenchmarkDetails(c flamego.Context, r flamego.Render) { + // find benchmark ID from request + benchmarkID := c.Query("benchmark_id") + + // find benchmark from DB + var benchmark models.Benchmark + models.DB.First(&benchmark, benchmarkID) + + // return JSON response + r.JSON(200, benchmark) +} + +func ApiV1ResultAdd(c flamego.Context, form forms.ResultForm, errs binding.Errors, r flamego.Render) { + if len(errs) > 0 { + var err error + switch errs[0].Category { + case binding.ErrorCategoryValidation: + err = errs[0].Err.(validator.ValidationErrors)[0] + default: + err = errs[0].Err + } + log.Fatal(err) + } + + result := models.Result{ + TestID: form.Test, + BenchmarkID: form.Benchmark, + AverageScore: form.AverageScore, + MinimumScore: form.MinimumScore, + MaximumScore: form.MaximumScore, + } + + _ = models.DB.Create(&result) + + r.JSON(200, "success") +} + +func ApiV1ResultList(c flamego.Context, r flamego.Render) { + // find benchmark and test IDs from request + benchmarkID := c.Query("benchmark_id") + testID := c.Query("test_id") + + // find results from the DB that match the benchmark and test + var results []models.Result + models.DB.Where("test_id = ? AND benchmark_id = ?", testID, benchmarkID).Find(&results) + + // return JSON response + r.JSON(200, results) +} diff --git a/web/routes/result.go b/web/routes/result.go index 6d1e4ba..e95831d 100644 --- a/web/routes/result.go +++ b/web/routes/result.go @@ -26,7 +26,6 @@ func ResultPostCreate(c flamego.Context, form forms.ResultForm, errs binding.Err result := models.Result{ TestID: form.Test, - HardwareID: form.Hardware, BenchmarkID: form.Benchmark, AverageScore: form.AverageScore, MinimumScore: form.MinimumScore,