Use PAS UI

This commit is contained in:
2025-05-20 20:41:26 +02:00
parent 90f1c4738e
commit 6b8ae2f236
17 changed files with 794 additions and 100 deletions

78
cmd/view/cdsDetails.go Normal file
View File

@@ -0,0 +1,78 @@
package view
import (
"api-cds-search/cmd/model"
"fmt"
"net/http"
"code.achtarmig.org/pas/ui/element"
"code.achtarmig.org/pas/ui/element/container"
"code.achtarmig.org/pas/ui/element/input"
"code.achtarmig.org/pas/ui/element/option"
"code.achtarmig.org/pas/ui/element/table"
"code.achtarmig.org/pas/ui/element/view"
"code.achtarmig.org/pas/ui/route"
)
func cdsDetails() {
view.New("CDSDetails", func(p *view.Element) {
route.Register("/cds", p)
p.Title = "CDSDetails"
p.OnRequest = onRequestDetails
container.New(p, "Details", func(p *container.Element) {
p.Justify = option.JustifyCenter
input.New(p, "q", input.TypeText, func(p *input.Element) {
p.Placeholder = "CDSViewTechnicalName"
p.Shape = option.ShapeRound
p.SetHTMX(element.HTMX{
Method: http.MethodGet,
Target: "#DetailsTable",
URL: "/cds",
PushURL: true,
})
})
})
container.New(p, "", func(p *container.Element) {
p.Justify = option.JustifyCenter
table.New(p, "DetailsTable", func(p *table.Element) {
p.MinWidth = 20
p.MaxWidth = 32
})
})
})
}
func onRequestDetails(e *view.Element, w http.ResponseWriter, r *http.Request) view.ProcessElements {
cds, _ := e.GetElement("q").(*input.Element).GetDataText()
e.Title = fmt.Sprintf("CDSDetails - %s", cds)
fields, err := model.GetCDSViewModelFields(cds)
if err != nil {
fmt.Println(err)
return view.ProcessElements{}
}
table := e.GetElement("DetailsTable").(*table.Element)
table.SetData(*fields)
for _, header := range table.Data.Header {
switch header.Name {
case "FieldNameOut":
header.Option.Font = option.FontMonospaced
case "DataTypeTitle":
case "FieldLengthOut":
header.Option.Font = option.FontMonospaced
case "DescriptionOut":
default:
header.Option.Hidden = true
}
}
table.Data.SetFieldOrder("FieldNameOut", "DescriptionOut", "DataTypeTitle", "FieldLengthOut")
return view.ProcessElements{
Partial: []element.ElementInterface{e.GetElement("DetailsTable")},
}
}

6
cmd/view/load.go Normal file
View File

@@ -0,0 +1,6 @@
package view
func Load() {
searchView()
cdsDetails()
}

50
cmd/view/results.go Normal file
View File

@@ -0,0 +1,50 @@
package view
import (
"api-cds-search/cmd/model"
"errors"
"net/http"
"net/url"
"code.achtarmig.org/pas/ui/element"
"code.achtarmig.org/pas/ui/element/boxedlist"
"code.achtarmig.org/pas/ui/element/boxedlist/expander"
"code.achtarmig.org/pas/ui/element/option"
"code.achtarmig.org/pas/ui/element/placeholder"
"code.achtarmig.org/pas/ui/element/view"
)
func results(v *view.Element, m *model.ResultsModel) element.ElementInterface {
cont := v.GetElement("SearchResultsContainer")
cont.DeleteAllChildren()
bl, _ := boxedlist.New(cont, "", func(p *boxedlist.Element) {
p.MaxWidth = 42
p.MinWidth = 20
for _, result := range m.Views {
expander.New(p, func(p *expander.Element) {
p.Title = result.DisplayName.String()
p.Subtitle = result.TechnicalName.String()
p.PlaceholderHeight = 21 * result.NumberOfFields
p.CallbackLazyLoad = func(e *expander.Element, w http.ResponseWriter, r *http.Request) error {
http.Redirect(w, r, "/cds?q="+url.QueryEscape(result.TechnicalName.String()), http.StatusSeeOther)
return errors.New("redirect")
}
})
}
})
return bl
}
func noResults(v *view.Element) element.ElementInterface {
cont := v.GetElement("SearchResultsContainer")
cont.DeleteAllChildren()
pl, _ := placeholder.New(cont, "", func(p *placeholder.Element) {
p.Icon = option.IconLoupe
p.Title = "No Results"
p.Subtitle = "Try refining your search term"
})
return pl
}

152
cmd/view/search.go Normal file
View File

@@ -0,0 +1,152 @@
package view
import (
"api-cds-search/cmd/search"
"net/http"
"code.achtarmig.org/pas/ui/element"
"code.achtarmig.org/pas/ui/element/button"
"code.achtarmig.org/pas/ui/element/container"
"code.achtarmig.org/pas/ui/element/form"
"code.achtarmig.org/pas/ui/element/input"
"code.achtarmig.org/pas/ui/element/option"
"code.achtarmig.org/pas/ui/element/placeholder"
"code.achtarmig.org/pas/ui/element/view"
"code.achtarmig.org/pas/ui/route"
)
func noSearch(v *view.Element) element.ElementInterface {
cont := v.GetElement("SearchResultsContainer")
cont.DeleteAllChildren()
pl, _ := placeholder.New(cont, "", func(p *placeholder.Element) {
p.Icon = option.IconLoupe
p.Title = "Search CDS-Views"
p.Subtitle = "Find CDS-Views from the Business Accelerator Hub"
})
return pl
}
func searchView() {
view.New("Search", func(p *view.Element) {
route.Register("/search", p)
p.Title = "CDS-Search"
p.OnRequest = func(v *view.Element, w http.ResponseWriter, r *http.Request) view.ProcessElements {
inputQuery := v.GetElement("q").(*input.Element)
inputQueryValue, _ := v.GetElement("q").(*input.Element).GetDataText()
searchTerm := search.GetSearchTerm(inputQueryValue)
if inputQueryValue == "" {
noSearch(v)
}
inputPage := v.GetElement("p").(*input.Element)
inputMaxPage := v.GetElement("MaxPage").(*input.Element)
currentPage, _ := inputPage.GetDataNumber()
if inputQuery.GetDataChanged() && inputQueryValue != "" {
buf, err := search.GetBuffer(searchTerm)
if err != nil {
search.BuildBuffer(searchTerm)
buf, err = search.GetBuffer(searchTerm)
}
if err != nil {
noResults(v)
} else {
currentPage, maxPage := search.GetPages(buf, currentPage)
m := search.Search(buf, currentPage, maxPage)
inputPage.Max = m.MaxPage
inputMaxPage.Min = m.MaxPage
inputMaxPage.Max = m.MaxPage
inputMaxPage.SetData(m.MaxPage)
results(v, m)
}
}
return view.ProcessElements{
Partial: []element.ElementInterface{v.GetElement("SearchResultsContainer")},
OOBUpdate: []element.ElementInterface{inputPage, inputMaxPage},
}
}
container.New(p, "MainContainer", func(p *container.Element) {
p.Justify = option.JustifyCenter
form.New(p, "SearchForm", func(p *form.Element) {
p.SetHTMX(element.HTMX{
Method: http.MethodGet,
Target: "#SearchResultsContainer>*",
Swap: "outerHTML",
URL: "/search",
PushURL: true,
Params: "q, p",
})
container.New(p, "SearchFormLinked", func(p *container.Element) {
p.Justify = option.JustifyCenter
p.LinkedHorizontal = true
input.New(p, "q", input.TypeText, func(p *input.Element) {
p.Placeholder = "Search here"
p.Shape = option.ShapeRound
p.MinWidth = 10
p.MaxWidth = 36
})
button.New(p, "SearchButton", func(p *button.Element) {
p.Label = "Search"
p.DisplayStyle = option.DisplayStyleSuggestedAction
p.Shape = option.ShapeRound
p.MaxWidth = 6
})
})
})
})
container.New(p, "CenterPager", func(p *container.Element) {
p.Justify = option.JustifyCenter
container.New(p, "Pager", func(p *container.Element) {
p.MaxWidth = 42
p.MinWidth = 10
p.Justify = option.JustifyRight
p.LinkedHorizontal = true
input.New(p, "p", input.TypeNumber, func(p *input.Element) {
p.Shape = option.ShapeRound
p.SetMin = true
p.Min = 0
p.SetMax = true
p.Max = 0
p.MinWidth = 4
p.SetHTMX(element.HTMX{
Method: http.MethodGet,
Include: "[name='q'], [name='p']",
Target: "#SearchResultsContainer>*",
URL: "/search",
Swap: "outerHTML",
PushURL: true,
})
})
input.New(p, "MaxPage", input.TypeNumber, func(p *input.Element) {
p.Disabled = true
p.Shape = option.ShapeRound
p.MinWidth = 4
p.SetMin = true
p.SetMax = true
})
})
})
container.New(p, "SearchResultsContainer", func(p *container.Element) {
p.Justify = option.JustifyCenter
})
})
}