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 }}
-
+
Benchmark |
+ Scoring Type |
+ # of Results |
Average |
Minimum |
Maximum |
- {{ range $res := .test.Results }}
-
- {{ $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 }} |
-
+ {{ range $benchmark := .test.Benchmarks }}
+
{{ 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,