427 lines
6.8 KiB
Go
Executable file
427 lines
6.8 KiB
Go
Executable file
package main
|
|
|
|
import (
|
|
"database/sql"
|
|
"fmt"
|
|
)
|
|
|
|
// Web
|
|
|
|
type NavItem struct {
|
|
Caption string
|
|
Destination string
|
|
}
|
|
|
|
func NewNavItem(caption, destination string) NavItem {
|
|
return NavItem{caption, destination}
|
|
}
|
|
|
|
type Stylename string
|
|
|
|
func NewStyleItemList(stylenames ...Stylename) []Stylename {
|
|
return stylenames
|
|
}
|
|
|
|
type TableColumns []string
|
|
|
|
type TableRow struct {
|
|
Columns TableColumns
|
|
Id int
|
|
}
|
|
|
|
type Table struct {
|
|
Collumns TableColumns
|
|
Rows []TableRow
|
|
}
|
|
|
|
func (t Table) FilterColumns(indices ...int) (Table, error) {
|
|
table := Table{}
|
|
|
|
for _, i := range indices {
|
|
if i < 0 || i >= len(t.Collumns) {
|
|
return table, fmt.Errorf("Index out of bounds: expected: 0-%v: actual: %v", len(t.Collumns), i)
|
|
}
|
|
}
|
|
|
|
table.Collumns = make(TableColumns, len(indices))
|
|
|
|
for i, I := range indices {
|
|
table.Collumns[i] = t.Collumns[I]
|
|
}
|
|
|
|
table.Rows = make([]TableRow, len(t.Rows))
|
|
|
|
for i, r := range t.Rows {
|
|
table.Rows[i] = TableRow{}
|
|
table.Rows[i].Id = r.Id
|
|
table.Rows[i].Columns = make(TableColumns, len(indices))
|
|
for j, I := range indices {
|
|
table.Rows[i].Columns[j] = t.Rows[i].Columns[I]
|
|
}
|
|
}
|
|
|
|
return table, nil
|
|
}
|
|
|
|
type HtmlElement interface {
|
|
HtmlTag() string
|
|
}
|
|
|
|
type InputField struct {
|
|
Id string
|
|
Type string
|
|
Label string
|
|
Name string
|
|
Value string
|
|
IsRequired bool
|
|
}
|
|
|
|
func (i *InputField) HtmlTag() string {
|
|
return "input"
|
|
}
|
|
|
|
type Option struct {
|
|
Caption string
|
|
Value string
|
|
Selected bool
|
|
}
|
|
|
|
type Select struct {
|
|
Id string
|
|
Label string
|
|
Name string
|
|
Options []*Option
|
|
IsRequired bool
|
|
}
|
|
|
|
func (s *Select) HtmlTag() string {
|
|
return "select"
|
|
}
|
|
|
|
type TextArea struct {
|
|
Id string
|
|
Label string
|
|
Name string
|
|
Value string
|
|
IsRequired bool
|
|
}
|
|
|
|
func (t *TextArea) HtmlTag() string {
|
|
return "textarea"
|
|
}
|
|
|
|
type Form struct {
|
|
RowId int
|
|
Table string
|
|
Elements []HtmlElement
|
|
}
|
|
|
|
// Database
|
|
|
|
type Location struct {
|
|
Id sql.NullInt64
|
|
Parent sql.NullInt64
|
|
Name sql.NullString
|
|
Description sql.NullString
|
|
Connection *Connection
|
|
}
|
|
|
|
func (l *Location) ToForm() (Form, error) {
|
|
form := Form{}
|
|
if l.Id.Valid {
|
|
form.RowId = int(l.Id.Int64)
|
|
}
|
|
|
|
form.Table = "locations"
|
|
form.Elements = make([]HtmlElement, 3)
|
|
|
|
lOptions := make([]*Option, 0)
|
|
|
|
locations, err := l.Connection.QueryLocations()
|
|
if err == nil {
|
|
lOptions, err = LocationsToOption(locations, l)
|
|
for i, o := range lOptions {
|
|
if o == nil {
|
|
fmt.Println(i)
|
|
}
|
|
}
|
|
}
|
|
if err != nil {
|
|
fmt.Println(err)
|
|
}
|
|
|
|
parentInput := &Select{
|
|
Id: "parent",
|
|
Label: "Übergeordneter Ort",
|
|
Name: "parent",
|
|
Options: lOptions,
|
|
}
|
|
|
|
nameInput := &InputField{
|
|
Id: "name",
|
|
Type: "text",
|
|
Label: "Name",
|
|
Name: "name",
|
|
}
|
|
|
|
descInput := &InputField{
|
|
Id: "description",
|
|
Type: "text",
|
|
Label: "Beschreibung",
|
|
Name: "description",
|
|
}
|
|
|
|
form.Elements[0] = parentInput
|
|
|
|
if l.Name.Valid {
|
|
nameInput.Value = fmt.Sprintf("%v", l.Name.String)
|
|
} else {
|
|
nameInput.Value = ""
|
|
}
|
|
form.Elements[1] = nameInput
|
|
|
|
if l.Description.Valid {
|
|
descInput.Value = fmt.Sprintf("%v", l.Description.String)
|
|
} else {
|
|
descInput.Value = ""
|
|
}
|
|
form.Elements[2] = descInput
|
|
|
|
return form, nil
|
|
}
|
|
|
|
func (l *Location) ToTableRow() TableRow {
|
|
columns := make(TableColumns, 3)
|
|
|
|
tr := TableRow{}
|
|
|
|
var path string
|
|
|
|
if l.Id.Valid {
|
|
columns[0] = fmt.Sprintf("%d", l.Id.Int64)
|
|
tr.Id = int(l.Id.Int64)
|
|
path, _ = l.Connection.QueryLocationFullPath(l.Id.Int64)
|
|
} else {
|
|
columns[0] = "NULL"
|
|
tr.Id = -1
|
|
}
|
|
columns[1] = path
|
|
if l.Description.Valid {
|
|
columns[2] = l.Description.String
|
|
} else {
|
|
columns[2] = "NULL"
|
|
}
|
|
|
|
tr.Columns = columns
|
|
|
|
return tr
|
|
}
|
|
|
|
func (l *Location) GetParent() *Location {
|
|
return nil
|
|
}
|
|
|
|
func (l *Location) FullPath() (string, error) {
|
|
return l.Connection.QueryLocationFullPath(l.Id.Int64)
|
|
}
|
|
|
|
type Container struct {
|
|
Id sql.NullInt64
|
|
Name sql.NullString
|
|
}
|
|
|
|
func (c *Container) ToForm() Form {
|
|
form := Form{}
|
|
if c.Id.Valid {
|
|
form.RowId = int(c.Id.Int64)
|
|
} else {
|
|
return form
|
|
}
|
|
|
|
form.Table = "containers"
|
|
|
|
form.Elements = make([]HtmlElement, 1)
|
|
|
|
nameInput := InputField{
|
|
"name",
|
|
"text",
|
|
"Name",
|
|
"name",
|
|
"",
|
|
true,
|
|
}
|
|
|
|
if c.Name.Valid {
|
|
nameInput.Value = c.Name.String
|
|
}
|
|
|
|
form.Elements[0] = &nameInput
|
|
|
|
return form
|
|
}
|
|
|
|
func (c *Container) ToTableRow() TableRow {
|
|
columns := make(TableColumns, 2)
|
|
|
|
tr := TableRow{}
|
|
|
|
if c.Id.Valid {
|
|
columns[0] = fmt.Sprintf("%d", c.Id.Int64)
|
|
tr.Id = int(c.Id.Int64)
|
|
} else {
|
|
columns[0] = "NULL"
|
|
tr.Id = -1
|
|
}
|
|
if c.Name.Valid {
|
|
columns[1] = c.Name.String
|
|
} else {
|
|
columns[1] = "NULL"
|
|
}
|
|
|
|
tr.Columns = columns
|
|
|
|
return tr
|
|
}
|
|
|
|
type Part struct {
|
|
Id sql.NullInt64
|
|
Name sql.NullString
|
|
Tags sql.NullString
|
|
Location Location
|
|
Container Container
|
|
Connection *Connection
|
|
}
|
|
|
|
func (p *Part) ToTableRow() TableRow {
|
|
columns := make(TableColumns, 5)
|
|
|
|
tr := TableRow{}
|
|
|
|
if p.Id.Valid {
|
|
columns[0] = fmt.Sprintf("%d", p.Id.Int64)
|
|
tr.Id = int(p.Id.Int64)
|
|
} else {
|
|
columns[0] = "NULL"
|
|
tr.Id = -1
|
|
}
|
|
if p.Name.Valid {
|
|
columns[1] = p.Name.String
|
|
} else {
|
|
columns[1] = "NULL"
|
|
}
|
|
if p.Tags.Valid {
|
|
columns[2] = p.Tags.String
|
|
} else {
|
|
columns[2] = "NULL"
|
|
}
|
|
if p.Location.Id.Valid {
|
|
fullPath, err := p.Connection.QueryLocationFullPath(p.Location.Id.Int64)
|
|
if err != nil {
|
|
fmt.Println(err)
|
|
}
|
|
columns[3] = fullPath
|
|
} else {
|
|
columns[3] = "NULL"
|
|
}
|
|
if p.Container.Name.Valid {
|
|
columns[4] = p.Container.Name.String
|
|
} else {
|
|
columns[4] = "NULL"
|
|
}
|
|
|
|
tr.Columns = columns
|
|
|
|
return tr
|
|
}
|
|
|
|
func (p *Part) ToForm() Form {
|
|
form := Form{}
|
|
if p.Id.Valid {
|
|
form.RowId = int(p.Id.Int64)
|
|
} else {
|
|
return form
|
|
}
|
|
|
|
form.Table = "parts"
|
|
|
|
form.Elements = make([]HtmlElement, 4)
|
|
|
|
nameInput := InputField{
|
|
"name",
|
|
"text",
|
|
"Name",
|
|
"name",
|
|
"",
|
|
true,
|
|
}
|
|
|
|
if p.Name.Valid {
|
|
nameInput.Value = p.Name.String
|
|
}
|
|
|
|
tagsInput := TextArea{
|
|
"tags",
|
|
"Tags",
|
|
"tags",
|
|
"",
|
|
true,
|
|
}
|
|
|
|
if p.Tags.Valid {
|
|
tagsInput.Value = p.Tags.String
|
|
}
|
|
|
|
lOptions := make([]*Option, 0)
|
|
|
|
locations, err := p.Connection.QueryLocations()
|
|
if err == nil {
|
|
lOptions, err = LocationsToOption(locations, &p.Location)
|
|
for i, o := range lOptions {
|
|
if o == nil {
|
|
fmt.Println(i)
|
|
}
|
|
}
|
|
}
|
|
if err != nil {
|
|
fmt.Println(err)
|
|
}
|
|
|
|
locationInput := Select{
|
|
Id: "location",
|
|
Label: "Ort",
|
|
Name: "location",
|
|
Options: lOptions,
|
|
}
|
|
|
|
cOptions := make([]*Option, 0)
|
|
|
|
containers, err := p.Connection.QueryContainers()
|
|
if err == nil {
|
|
cOptions, err = ContainersToOption(containers, &p.Container)
|
|
for i, o := range lOptions {
|
|
if o == nil {
|
|
fmt.Println(i)
|
|
}
|
|
}
|
|
}
|
|
|
|
containerInput := Select{
|
|
Id: "container",
|
|
Label: "Behälter",
|
|
Name: "container",
|
|
Options: cOptions,
|
|
}
|
|
|
|
form.Elements[0] = &nameInput
|
|
form.Elements[1] = &tagsInput
|
|
form.Elements[2] = &locationInput
|
|
form.Elements[3] = &containerInput
|
|
|
|
return form
|
|
}
|
|
|
|
// Interfaces
|
|
|
|
type DatabaseType interface {
|
|
ToTableRow() TableRow
|
|
}
|