Skip to content

Commit

Permalink
Merge pull request #160 from vsimakhin/fix/map-parameter-decode
Browse files Browse the repository at this point in the history
Fix/map parameter decode
  • Loading branch information
vsimakhin authored Sep 20, 2023
2 parents 2a240b4 + fc85298 commit ce62894
Show file tree
Hide file tree
Showing 7 changed files with 135 additions and 9 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

## [Unreleased]

- Fix: The filter on the `Map` page wasn't working correctly if there was a space in the fields
- Update: Show the total number of rows for most of the tables (Logbook, Licensing, Airports)
- New: Date Range Picker first day of the week settings - Sunday or Monday.
- New: Attachments synchronization support for the mobile application.
Expand Down
25 changes: 20 additions & 5 deletions cmd/web/handlers_map.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ package main
import (
"net/http"
"strconv"
"strings"

"github.com/vsimakhin/web-logbook/internal/maprender"
"github.com/vsimakhin/web-logbook/internal/models"
Expand All @@ -17,8 +16,24 @@ func (app *application) HandlerMap(w http.ResponseWriter, r *http.Request) {
app.errorLog.Printf("cannot get aircraft classes - %s", err)
}

models, err := app.db.GetAircraftModels()
if err != nil {
app.errorLog.Println(err)
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}

regs, err := app.db.GetAircraftRegs()
if err != nil {
app.errorLog.Println(err)
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}

data := make(map[string]interface{})
data["classes"] = classes
data["models"] = models
data["regs"] = regs

if err := app.renderTemplate(w, r, "map", &templateData{Data: data}, "common-js", "map-js"); err != nil {
app.errorLog.Println(err)
Expand All @@ -31,10 +46,10 @@ func (app *application) HandlerMapData(w http.ResponseWriter, r *http.Request) {
// get filter parameters
startDate := r.URL.Query().Get("start_date")
endDate := r.URL.Query().Get("end_date")
aircraftReg := strings.TrimSpace(r.URL.Query().Get("reg"))
aircraftModel := r.URL.Query().Get("model")
aircraftClass := r.URL.Query().Get("class")
routePlace := r.URL.Query().Get("place")
aircraftReg := decodeParameter(r, "reg")
aircraftModel := decodeParameter(r, "model")
aircraftClass := decodeParameter(r, "class")
routePlace := decodeParameter(r, "place")
filterNoRoutes, _ := strconv.ParseBool(r.URL.Query().Get("filter_noroutes"))

flightRecords, err := app.db.GetFlightRecords()
Expand Down
2 changes: 2 additions & 0 deletions cmd/web/handlers_map_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ func TestHandlerMap(t *testing.T) {

models.AddMock(mock, "GetSettings")
models.AddMock(mock, "GetSettings")
models.AddMock(mock, "GetAircraftsModels")
models.AddMock(mock, "GetAircraftsRegs")

srv := httptest.NewServer(app.routes())
defer srv.Close()
Expand Down
11 changes: 11 additions & 0 deletions cmd/web/helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"io"
"net"
"net/http"
"net/url"
"regexp"
"strings"
"time"
Expand Down Expand Up @@ -272,3 +273,13 @@ func (app *application) getServerUrls() []string {

return urls
}

func decodeParameter(r *http.Request, parameter string) string {
encoded := r.URL.Query().Get(parameter)
decoded, err := url.QueryUnescape(encoded)
if err != nil {
return encoded
}

return strings.TrimSpace(decoded)
}
23 changes: 19 additions & 4 deletions cmd/web/templates/map.page.gohtml
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,8 @@

{{ define "content" }}
{{$classes := index .Data "classes"}}
{{$models := index .Data "models"}}
{{$regs := index .Data "regs"}}
<div class="row">
<div class="col-md-2">
<div class="row">
Expand All @@ -64,12 +66,22 @@
</div>
<div class="mb-2">
<label for="filter_registration" class="form-label">Aircraft filters:</label>
<input class="form-control form-control-sm" type="text" id="filter_registration"
name="filter_registration" autocomplete="off" placeholder="Aircraft Registraton">
<input class="form-select form-select-sm" type="text" id="filter_registration"
name="filter_registration" autocomplete="off" placeholder="Aircraft Registraton" list="aircraft_regs_options">
<datalist id="aircraft_regs_options">
{{ range $key, $element := $regs}}
<option value="{{ $element }}">
{{ end}}
</datalist>
</div>
<div class="mb-2">
<input class="form-control form-control-sm" type="text" id="filter_model"
name="filter_model" autocomplete="off" placeholder="Aircraft Model">
<input class="form-select form-select-sm" type="text" id="filter_model"
name="filter_model" autocomplete="off" placeholder="Aircraft Model/Type" list="aircraft_models_options">
<datalist id="aircraft_models_options">
{{ range $key, $element := $models}}
<option value="{{ $element }}">
{{ end}}
</datalist>
</div>
<div class="mb-2">
<input class="form-select form-select-sm" type="text" id="filter_class"
Expand Down Expand Up @@ -98,6 +110,9 @@
<div id="some_stats"></div>
</div>
<hr>
<div class="alert alert-info row">
The Aicraft and Route filters works in the way "string contains substring" or "*filter*". So aircraft type "C172" will include "C172" and "C172RG"
</div>
</div>
<div class="col-md-10">
<div id="map" class="ol-map"></div>
Expand Down
62 changes: 62 additions & 0 deletions internal/models/aircrafts.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,68 @@ func (m *DBModel) GetAircrafts(condition int) (map[string]string, error) {
return aircrafts, nil
}

// GetAircraftModels returns the list of the recorded aircraft models/types
func (m *DBModel) GetAircraftModels() ([]string, error) {
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()

var models []string

var query string
var model string

query = "SELECT aircraft_model FROM logbook_view WHERE aircraft_model <> '' " +
"GROUP BY aircraft_model ORDER BY aircraft_model"
rows, err := m.DB.QueryContext(ctx, query)

if err != nil {
return models, err
}
defer rows.Close()

for rows.Next() {
err = rows.Scan(&model)

if err != nil {
return models, err
}
models = append(models, model)
}

return models, nil
}

// GetAircraftRegs returns the list of the recorded aircraft registrations
func (m *DBModel) GetAircraftRegs() ([]string, error) {
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()

var regs []string

var query string
var reg string

query = "SELECT reg_name FROM logbook_view WHERE reg_name <> '' " +
"GROUP BY reg_name ORDER BY reg_name"
rows, err := m.DB.QueryContext(ctx, query)

if err != nil {
return regs, err
}
defer rows.Close()

for rows.Next() {
err = rows.Scan(&reg)

if err != nil {
return regs, err
}
regs = append(regs, reg)
}

return regs, nil
}

// GetAircraftClasses returns aircraft clasess
func (m *DBModel) GetAircraftClasses() (map[string]string, error) {

Expand Down
20 changes: 20 additions & 0 deletions internal/models/models_mock.go
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,26 @@ func InitSQLMockValues() {
},
}

SQLMock["GetAircraftsModels"] = Mock{
Query: "SELECT (.+) FROM logbook_view WHERE aircraft_model <> '' GROUP BY aircraft_model ORDER BY aircraft_model",
Rows: []string{
"aircraft_model",
},
Values: []driver.Value{
"MODEL",
},
}

SQLMock["GetAircraftsRegs"] = Mock{
Query: "SELECT (.+) FROM logbook_view WHERE reg_name <> '' GROUP BY reg_name ORDER BY reg_name",
Rows: []string{
"reg_name",
},
Values: []driver.Value{
"REG",
},
}

// GetAirportByID
SQLMock["GetAirportByID"] = Mock{
Query: "SELECT (.+) FROM airports_view WHERE",
Expand Down

0 comments on commit ce62894

Please sign in to comment.