Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions SECURE_DATA_FLOW.md
Original file line number Diff line number Diff line change
Expand Up @@ -96,9 +96,10 @@ Template variables excerpt:
window.userToken = "{{.TempToken}}"; // Secure token in memory only

if (!window.userToken || window.userToken.trim() === "") {
document.getElementById("youNeedToAuthenticate").style.display = "block";
document.getElementById("youNeedToAuthenticate").classList.remove("d-none");
} else {
document.getElementById("mainContent").style.display = "flex";
document.getElementById("mainContent").classList.remove("d-none");
document.getElementById("mainContent").classList.add("d-flex");
}
</script>
```
Expand Down
45 changes: 42 additions & 3 deletions forms.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,19 +6,22 @@ import (
"fmt"
"log"
"os"
"regexp"
"strings"
"sync"
"time"

"github.com/couchbase/gocb/v2"
"golang.org/x/text/cases"
"golang.org/x/text/language"
"gopkg.in/yaml.v3"
)

type TopNavData struct {
FlagLogo string
GovLogo string
HttpsLogo string
TransparentGif string
TransparentPng string
ProductLink string
ProductText string
AgencyLink string
Expand All @@ -31,6 +34,7 @@ type TopNavData struct {

type FormTemplate struct {
TemplateName string
PrettyTemplateName string
Fields map[string]interface{}
SelectFields map[string][]string
SelectModes map[string]string
Expand Down Expand Up @@ -198,6 +202,40 @@ func UpsertFormData(id string, data map[string]interface{}) error {
return nil
}

// SnakeCaseToTitleCase converts a snake_case string to Title Case.
func SnakeCaseToTitleCase(s string) string {
// First, replace underscores with spaces to treat them as word boundaries
withSpaces := strings.ReplaceAll(s, "_", " ")

// Use the modern cases package for proper Unicode title casing
// We use an impartial caser for general English text
caser := cases.Title(language.Und, cases.NoLower)

// Apply title case
titleCase := caser.String(withSpaces)

return titleCase
}

// camelToTitle uses a regex to split the camel case string and then applies proper title casing.
func CamelCaseToTitleCase(s string) string {
// Add a space before any uppercase letter that is not at the start of the string
// or part of a sequence of uppercase letters followed by a lowercase letter (to handle abbreviations correctly)
re := regexp.MustCompile("([a-z0-9])([A-Z])")
spaced := re.ReplaceAllString(s, "$1 $2")

// The regex above will correctly handle things like "myHTMLParser" to "my HTML Parser",
// but for "HTMLParser" it will just be "HTMLParser". This is a complex problem.
// For general use, the simple regex is often sufficient.

// Now, use the recommended cases package for locale-aware title casing
// Choose a language tag, e.g., English
caser := cases.Title(language.English)
titleStr := caser.String(spaced)

return titleStr
}

// GetFormTemplates retrieves all form templates from the Couchbase COMMON collection, parses them into FormTemplate structs,
// and returns a slice of these templates.
func GetFormTemplates() ([]FormTemplate, error) {
Expand All @@ -219,6 +257,7 @@ func GetFormTemplates() ([]FormTemplate, error) {
continue
}
t.TemplateName, _ = common["templateName"].(string)
t.PrettyTemplateName = SnakeCaseToTitleCase(common["templateName"].(string))
t.TemplateFieldCustomLabels = getTemplateFieldCustomLabels(common)
t.RootPath = RootPath()
fields := make(map[string]interface{}, 0)
Expand Down Expand Up @@ -334,9 +373,9 @@ func getTemplateFieldCustomLabels(common map[string]any) map[string]string {
// fill all the empty labels with the default values
for field := range common["template"].(map[string]any) {
if label, exists := templateFieldCustomLabels[field]; !exists || label == "" {
templateFieldCustomLabels[field] = field
templateFieldCustomLabels[field] = strings.ReplaceAll(CamelCaseToTitleCase(field), "Dsg", "DSG ")
} else {
templateFieldCustomLabels[field] = label
templateFieldCustomLabels[field] = strings.ReplaceAll(CamelCaseToTitleCase(label), "Dsg", "DSG ")
}
}
return templateFieldCustomLabels
Expand Down
9 changes: 6 additions & 3 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,8 @@ func main() {
r.Static(RootPath()+"/jsontree-js", "./static/jsontree-js-4.7.1/dist")
r.Static(RootPath()+"/static", "./static")
r.Static(RootPath()+"/img", "./static/img")
r.Static(RootPath()+"/css", "./static/css")
r.Static(RootPath()+"/bs", "./static/bootstrap-5.3.1-dist")
r.LoadHTMLGlob("templates/*")

root := RootPath()
Expand All @@ -123,14 +125,15 @@ func main() {
"FlagLogo": RootPath() + "/static/img/us_flag_small.png",
"GovLogo": RootPath() + "/static/img/icon-dot-gov.svg",
"HttpsLogo": RootPath() + "/static/img/icon-https.svg",
"TransparentGif": RootPath() + "/static/img/noaa_transparent.gif",
"TransparentPng": RootPath() + "/static/img/noaa_gsl_transparent.png",
"vxFormsLogo": RootPath() + "/static/img/vxFormsLogo.png",
"RootPath": RootPath(),
"ProductLink": RootPath() + "/",
"ProductText": "vxFormsUI",
"ProductText": "Verification Requests",
"AgencyLink": "https://gsl.noaa.gov/",
"AgencyText": "Global Systems Laboratory",
"BugsLink": "https://github.com/NOAA-GSL/vxFormsUI/issues",
"BugsText": "Bugs/Issues (GitHub)",
"BugsText": "GitHub",
"EmailText": "mailto:mats.gsl@noaa.gov?Subject=Feedback from vxFormsUI",
"UserRole": userRoleInfo.UserRole,
"UserEmail": userRoleInfo.UserInfo.Email, // Add user email here if available
Expand Down
Loading