Make organization.name not-nullable, consolidate org in dash context
This commit is contained in:
parent
4f0b73c769
commit
a4c0e367a8
13 changed files with 118 additions and 50 deletions
|
|
@ -131,7 +131,7 @@ func SignupUser(ctx context.Context, username string, name string, password stri
|
|||
return nil, fmt.Errorf("Cannot signup user, failed to create hashed password: %w", err)
|
||||
}
|
||||
o_setter := models.OrganizationSetter{
|
||||
Name: omitnull.From(fmt.Sprintf("%s's organization", username)),
|
||||
Name: omit.From(fmt.Sprintf("%s's organization", username)),
|
||||
ArcgisID: omitnull.From(""),
|
||||
ArcgisName: omitnull.From(""),
|
||||
FieldseekerURL: omitnull.From(""),
|
||||
|
|
|
|||
|
|
@ -213,6 +213,15 @@ var Districts = Table[
|
|||
Generated: false,
|
||||
AutoIncr: false,
|
||||
},
|
||||
Geom4326: column{
|
||||
Name: "geom_4326",
|
||||
DBType: "geometry",
|
||||
Default: "GENERATED",
|
||||
Comment: "",
|
||||
Nullable: true,
|
||||
Generated: true,
|
||||
AutoIncr: false,
|
||||
},
|
||||
},
|
||||
Indexes: districtIndexes{
|
||||
DistrictPkey: index{
|
||||
|
|
@ -282,11 +291,12 @@ type districtColumns struct {
|
|||
ShapeLe1 column
|
||||
ShapeArea column
|
||||
Geom column
|
||||
Geom4326 column
|
||||
}
|
||||
|
||||
func (c districtColumns) AsSlice() []column {
|
||||
return []column{
|
||||
c.Gid, c.ID, c.Website, c.Contact, c.Address, c.Regionid, c.PostalCod, c.Phone1, c.Fax1, c.Agency, c.Code1, c.City1, c.ShapeLeng, c.Address2, c.GeneralMG, c.City2, c.PostalC1, c.Fax2, c.Phone2, c.ShapeLe1, c.ShapeArea, c.Geom,
|
||||
c.Gid, c.ID, c.Website, c.Contact, c.Address, c.Regionid, c.PostalCod, c.Phone1, c.Fax1, c.Agency, c.Code1, c.City1, c.ShapeLeng, c.Address2, c.GeneralMG, c.City2, c.PostalC1, c.Fax2, c.Phone2, c.ShapeLe1, c.ShapeArea, c.Geom, c.Geom4326,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -27,9 +27,9 @@ var Organizations = Table[
|
|||
Name: column{
|
||||
Name: "name",
|
||||
DBType: "text",
|
||||
Default: "NULL",
|
||||
Default: "",
|
||||
Comment: "",
|
||||
Nullable: true,
|
||||
Nullable: false,
|
||||
Generated: false,
|
||||
AutoIncr: false,
|
||||
},
|
||||
|
|
|
|||
|
|
@ -118,6 +118,7 @@ func (f *Factory) FromExistingDistrict(m *models.District) *DistrictTemplate {
|
|||
o.ShapeLe1 = func() null.Val[decimal.Decimal] { return m.ShapeLe1 }
|
||||
o.ShapeArea = func() null.Val[decimal.Decimal] { return m.ShapeArea }
|
||||
o.Geom = func() null.Val[string] { return m.Geom }
|
||||
o.Geom4326 = func() null.Val[string] { return m.Geom4326 }
|
||||
|
||||
return o
|
||||
}
|
||||
|
|
@ -2317,7 +2318,7 @@ func (f *Factory) FromExistingOrganization(m *models.Organization) *Organization
|
|||
o := &OrganizationTemplate{f: f, alreadyPersisted: true}
|
||||
|
||||
o.ID = func() int32 { return m.ID }
|
||||
o.Name = func() null.Val[string] { return m.Name }
|
||||
o.Name = func() string { return m.Name }
|
||||
o.ArcgisID = func() null.Val[string] { return m.ArcgisID }
|
||||
o.ArcgisName = func() null.Val[string] { return m.ArcgisName }
|
||||
o.FieldseekerURL = func() null.Val[string] { return m.FieldseekerURL }
|
||||
|
|
|
|||
|
|
@ -59,6 +59,7 @@ type DistrictTemplate struct {
|
|||
ShapeLe1 func() null.Val[decimal.Decimal]
|
||||
ShapeArea func() null.Val[decimal.Decimal]
|
||||
Geom func() null.Val[string]
|
||||
Geom4326 func() null.Val[string]
|
||||
|
||||
f *Factory
|
||||
|
||||
|
|
@ -257,6 +258,9 @@ func (o DistrictTemplate) Build() *models.District {
|
|||
if o.Geom != nil {
|
||||
m.Geom = o.Geom()
|
||||
}
|
||||
if o.Geom4326 != nil {
|
||||
m.Geom4326 = o.Geom4326()
|
||||
}
|
||||
|
||||
o.setModelRels(m)
|
||||
|
||||
|
|
@ -399,6 +403,7 @@ func (m districtMods) RandomizeAllColumns(f *faker.Faker) DistrictMod {
|
|||
DistrictMods.RandomShapeLe1(f),
|
||||
DistrictMods.RandomShapeArea(f),
|
||||
DistrictMods.RandomGeom(f),
|
||||
DistrictMods.RandomGeom4326(f),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1546,6 +1551,59 @@ func (m districtMods) RandomGeomNotNull(f *faker.Faker) DistrictMod {
|
|||
})
|
||||
}
|
||||
|
||||
// Set the model columns to this value
|
||||
func (m districtMods) Geom4326(val null.Val[string]) DistrictMod {
|
||||
return DistrictModFunc(func(_ context.Context, o *DistrictTemplate) {
|
||||
o.Geom4326 = func() null.Val[string] { return val }
|
||||
})
|
||||
}
|
||||
|
||||
// Set the Column from the function
|
||||
func (m districtMods) Geom4326Func(f func() null.Val[string]) DistrictMod {
|
||||
return DistrictModFunc(func(_ context.Context, o *DistrictTemplate) {
|
||||
o.Geom4326 = f
|
||||
})
|
||||
}
|
||||
|
||||
// Clear any values for the column
|
||||
func (m districtMods) UnsetGeom4326() DistrictMod {
|
||||
return DistrictModFunc(func(_ context.Context, o *DistrictTemplate) {
|
||||
o.Geom4326 = nil
|
||||
})
|
||||
}
|
||||
|
||||
// Generates a random value for the column using the given faker
|
||||
// if faker is nil, a default faker is used
|
||||
// The generated value is sometimes null
|
||||
func (m districtMods) RandomGeom4326(f *faker.Faker) DistrictMod {
|
||||
return DistrictModFunc(func(_ context.Context, o *DistrictTemplate) {
|
||||
o.Geom4326 = func() null.Val[string] {
|
||||
if f == nil {
|
||||
f = &defaultFaker
|
||||
}
|
||||
|
||||
val := random_string(f)
|
||||
return null.From(val)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// Generates a random value for the column using the given faker
|
||||
// if faker is nil, a default faker is used
|
||||
// The generated value is never null
|
||||
func (m districtMods) RandomGeom4326NotNull(f *faker.Faker) DistrictMod {
|
||||
return DistrictModFunc(func(_ context.Context, o *DistrictTemplate) {
|
||||
o.Geom4326 = func() null.Val[string] {
|
||||
if f == nil {
|
||||
f = &defaultFaker
|
||||
}
|
||||
|
||||
val := random_string(f)
|
||||
return null.From(val)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func (m districtMods) WithParentsCascading() DistrictMod {
|
||||
return DistrictModFunc(func(ctx context.Context, o *DistrictTemplate) {
|
||||
if isDone, _ := districtWithParentsCascadingCtx.Value(ctx); isDone {
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@ func (mods OrganizationModSlice) Apply(ctx context.Context, n *OrganizationTempl
|
|||
// all columns are optional and should be set by mods
|
||||
type OrganizationTemplate struct {
|
||||
ID func() int32
|
||||
Name func() null.Val[string]
|
||||
Name func() string
|
||||
ArcgisID func() null.Val[string]
|
||||
ArcgisName func() null.Val[string]
|
||||
FieldseekerURL func() null.Val[string]
|
||||
|
|
@ -650,7 +650,7 @@ func (o OrganizationTemplate) BuildSetter() *models.OrganizationSetter {
|
|||
}
|
||||
if o.Name != nil {
|
||||
val := o.Name()
|
||||
m.Name = omitnull.FromNull(val)
|
||||
m.Name = omit.From(val)
|
||||
}
|
||||
if o.ArcgisID != nil {
|
||||
val := o.ArcgisID()
|
||||
|
|
@ -721,6 +721,10 @@ func (o OrganizationTemplate) BuildMany(number int) models.OrganizationSlice {
|
|||
}
|
||||
|
||||
func ensureCreatableOrganization(m *models.OrganizationSetter) {
|
||||
if !(m.Name.IsValue()) {
|
||||
val := random_string(nil)
|
||||
m.Name = omit.From(val)
|
||||
}
|
||||
}
|
||||
|
||||
// insertOptRels creates and inserts any optional the relationships on *models.Organization
|
||||
|
|
@ -1501,14 +1505,14 @@ func (m organizationMods) RandomID(f *faker.Faker) OrganizationMod {
|
|||
}
|
||||
|
||||
// Set the model columns to this value
|
||||
func (m organizationMods) Name(val null.Val[string]) OrganizationMod {
|
||||
func (m organizationMods) Name(val string) OrganizationMod {
|
||||
return OrganizationModFunc(func(_ context.Context, o *OrganizationTemplate) {
|
||||
o.Name = func() null.Val[string] { return val }
|
||||
o.Name = func() string { return val }
|
||||
})
|
||||
}
|
||||
|
||||
// Set the Column from the function
|
||||
func (m organizationMods) NameFunc(f func() null.Val[string]) OrganizationMod {
|
||||
func (m organizationMods) NameFunc(f func() string) OrganizationMod {
|
||||
return OrganizationModFunc(func(_ context.Context, o *OrganizationTemplate) {
|
||||
o.Name = f
|
||||
})
|
||||
|
|
@ -1523,32 +1527,10 @@ func (m organizationMods) UnsetName() OrganizationMod {
|
|||
|
||||
// Generates a random value for the column using the given faker
|
||||
// if faker is nil, a default faker is used
|
||||
// The generated value is sometimes null
|
||||
func (m organizationMods) RandomName(f *faker.Faker) OrganizationMod {
|
||||
return OrganizationModFunc(func(_ context.Context, o *OrganizationTemplate) {
|
||||
o.Name = func() null.Val[string] {
|
||||
if f == nil {
|
||||
f = &defaultFaker
|
||||
}
|
||||
|
||||
val := random_string(f)
|
||||
return null.From(val)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// Generates a random value for the column using the given faker
|
||||
// if faker is nil, a default faker is used
|
||||
// The generated value is never null
|
||||
func (m organizationMods) RandomNameNotNull(f *faker.Faker) OrganizationMod {
|
||||
return OrganizationModFunc(func(_ context.Context, o *OrganizationTemplate) {
|
||||
o.Name = func() null.Val[string] {
|
||||
if f == nil {
|
||||
f = &defaultFaker
|
||||
}
|
||||
|
||||
val := random_string(f)
|
||||
return null.From(val)
|
||||
o.Name = func() string {
|
||||
return random_string(f)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
|
|
|||
5
db/migrations/00030_organization_name_not_null.sql
Normal file
5
db/migrations/00030_organization_name_not_null.sql
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
-- +goose Up
|
||||
ALTER TABLE organization ALTER COLUMN name SET NOT NULL;
|
||||
|
||||
-- +goose Down
|
||||
ALTER TABLE organization ALTER COLUMN name DROP NOT NULL;
|
||||
|
|
@ -44,6 +44,7 @@ type District struct {
|
|||
ShapeLe1 null.Val[decimal.Decimal] `db:"shape_le_1" `
|
||||
ShapeArea null.Val[decimal.Decimal] `db:"shape_area" `
|
||||
Geom null.Val[string] `db:"geom" `
|
||||
Geom4326 null.Val[string] `db:"geom_4326,generated" `
|
||||
}
|
||||
|
||||
// DistrictSlice is an alias for a slice of pointers to District.
|
||||
|
|
@ -59,7 +60,7 @@ type DistrictsQuery = *psql.ViewQuery[*District, DistrictSlice]
|
|||
func buildDistrictColumns(alias string) districtColumns {
|
||||
return districtColumns{
|
||||
ColumnsExpr: expr.NewColumnsExpr(
|
||||
"gid", "id", "website", "contact", "address", "regionid", "postal_cod", "phone1", "fax1", "agency", "code1", "city1", "shape_leng", "address2", "general_mg", "city2", "postal_c_1", "fax2", "phone2", "shape_le_1", "shape_area", "geom",
|
||||
"gid", "id", "website", "contact", "address", "regionid", "postal_cod", "phone1", "fax1", "agency", "code1", "city1", "shape_leng", "address2", "general_mg", "city2", "postal_c_1", "fax2", "phone2", "shape_le_1", "shape_area", "geom", "geom_4326",
|
||||
).WithParent("district"),
|
||||
tableAlias: alias,
|
||||
Gid: psql.Quote(alias, "gid"),
|
||||
|
|
@ -84,6 +85,7 @@ func buildDistrictColumns(alias string) districtColumns {
|
|||
ShapeLe1: psql.Quote(alias, "shape_le_1"),
|
||||
ShapeArea: psql.Quote(alias, "shape_area"),
|
||||
Geom: psql.Quote(alias, "geom"),
|
||||
Geom4326: psql.Quote(alias, "geom_4326"),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -112,6 +114,7 @@ type districtColumns struct {
|
|||
ShapeLe1 psql.Expression
|
||||
ShapeArea psql.Expression
|
||||
Geom psql.Expression
|
||||
Geom4326 psql.Expression
|
||||
}
|
||||
|
||||
func (c districtColumns) Alias() string {
|
||||
|
|
@ -842,6 +845,7 @@ type districtWhere[Q psql.Filterable] struct {
|
|||
ShapeLe1 psql.WhereNullMod[Q, decimal.Decimal]
|
||||
ShapeArea psql.WhereNullMod[Q, decimal.Decimal]
|
||||
Geom psql.WhereNullMod[Q, string]
|
||||
Geom4326 psql.WhereNullMod[Q, string]
|
||||
}
|
||||
|
||||
func (districtWhere[Q]) AliasedAs(alias string) districtWhere[Q] {
|
||||
|
|
@ -872,5 +876,6 @@ func buildDistrictWhere[Q psql.Filterable](cols districtColumns) districtWhere[Q
|
|||
ShapeLe1: psql.WhereNull[Q, decimal.Decimal](cols.ShapeLe1),
|
||||
ShapeArea: psql.WhereNull[Q, decimal.Decimal](cols.ShapeArea),
|
||||
Geom: psql.WhereNull[Q, string](cols.Geom),
|
||||
Geom4326: psql.WhereNull[Q, string](cols.Geom4326),
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@ import (
|
|||
// Organization is an object representing the database table.
|
||||
type Organization struct {
|
||||
ID int32 `db:"id,pk" `
|
||||
Name null.Val[string] `db:"name" `
|
||||
Name string `db:"name" `
|
||||
ArcgisID null.Val[string] `db:"arcgis_id" `
|
||||
ArcgisName null.Val[string] `db:"arcgis_name" `
|
||||
FieldseekerURL null.Val[string] `db:"fieldseeker_url" `
|
||||
|
|
@ -117,7 +117,7 @@ func (organizationColumns) AliasedAs(alias string) organizationColumns {
|
|||
// Generated columns are not included
|
||||
type OrganizationSetter struct {
|
||||
ID omit.Val[int32] `db:"id,pk" `
|
||||
Name omitnull.Val[string] `db:"name" `
|
||||
Name omit.Val[string] `db:"name" `
|
||||
ArcgisID omitnull.Val[string] `db:"arcgis_id" `
|
||||
ArcgisName omitnull.Val[string] `db:"arcgis_name" `
|
||||
FieldseekerURL omitnull.Val[string] `db:"fieldseeker_url" `
|
||||
|
|
@ -128,7 +128,7 @@ func (s OrganizationSetter) SetColumns() []string {
|
|||
if s.ID.IsValue() {
|
||||
vals = append(vals, "id")
|
||||
}
|
||||
if !s.Name.IsUnset() {
|
||||
if s.Name.IsValue() {
|
||||
vals = append(vals, "name")
|
||||
}
|
||||
if !s.ArcgisID.IsUnset() {
|
||||
|
|
@ -147,8 +147,8 @@ func (s OrganizationSetter) Overwrite(t *Organization) {
|
|||
if s.ID.IsValue() {
|
||||
t.ID = s.ID.MustGet()
|
||||
}
|
||||
if !s.Name.IsUnset() {
|
||||
t.Name = s.Name.MustGetNull()
|
||||
if s.Name.IsValue() {
|
||||
t.Name = s.Name.MustGet()
|
||||
}
|
||||
if !s.ArcgisID.IsUnset() {
|
||||
t.ArcgisID = s.ArcgisID.MustGetNull()
|
||||
|
|
@ -174,8 +174,8 @@ func (s *OrganizationSetter) Apply(q *dialect.InsertQuery) {
|
|||
vals[0] = psql.Raw("DEFAULT")
|
||||
}
|
||||
|
||||
if !s.Name.IsUnset() {
|
||||
vals[1] = psql.Arg(s.Name.MustGetNull())
|
||||
if s.Name.IsValue() {
|
||||
vals[1] = psql.Arg(s.Name.MustGet())
|
||||
} else {
|
||||
vals[1] = psql.Raw("DEFAULT")
|
||||
}
|
||||
|
|
@ -216,7 +216,7 @@ func (s OrganizationSetter) Expressions(prefix ...string) []bob.Expression {
|
|||
}})
|
||||
}
|
||||
|
||||
if !s.Name.IsUnset() {
|
||||
if s.Name.IsValue() {
|
||||
exprs = append(exprs, expr.Join{Sep: " = ", Exprs: []bob.Expression{
|
||||
psql.Quote(append(prefix, "name")...),
|
||||
psql.Arg(s.Name),
|
||||
|
|
@ -3416,7 +3416,7 @@ func (organization0 *Organization) AttachUser(ctx context.Context, exec bob.Exec
|
|||
|
||||
type organizationWhere[Q psql.Filterable] struct {
|
||||
ID psql.WhereMod[Q, int32]
|
||||
Name psql.WhereNullMod[Q, string]
|
||||
Name psql.WhereMod[Q, string]
|
||||
ArcgisID psql.WhereNullMod[Q, string]
|
||||
ArcgisName psql.WhereNullMod[Q, string]
|
||||
FieldseekerURL psql.WhereNullMod[Q, string]
|
||||
|
|
@ -3429,7 +3429,7 @@ func (organizationWhere[Q]) AliasedAs(alias string) organizationWhere[Q] {
|
|||
func buildOrganizationWhere[Q psql.Filterable](cols organizationColumns) organizationWhere[Q] {
|
||||
return organizationWhere[Q]{
|
||||
ID: psql.Where[Q, int32](cols.ID),
|
||||
Name: psql.WhereNull[Q, string](cols.Name),
|
||||
Name: psql.Where[Q, string](cols.Name),
|
||||
ArcgisID: psql.WhereNull[Q, string](cols.ArcgisID),
|
||||
ArcgisName: psql.WhereNull[Q, string](cols.ArcgisName),
|
||||
FieldseekerURL: psql.WhereNull[Q, string](cols.FieldseekerURL),
|
||||
|
|
|
|||
|
|
@ -42,7 +42,6 @@ type ContextDashboard struct {
|
|||
IsSyncOngoing bool
|
||||
LastSync *time.Time
|
||||
MapData ComponentMap
|
||||
Org string
|
||||
RecentRequests []ServiceRequestSummary
|
||||
User User
|
||||
}
|
||||
|
|
@ -249,7 +248,6 @@ func dashboard(ctx context.Context, w http.ResponseWriter, user *models.User) {
|
|||
MapData: ComponentMap{
|
||||
MapboxToken: config.MapboxToken,
|
||||
},
|
||||
Org: org.Name.MustGet(),
|
||||
RecentRequests: requests,
|
||||
User: userContent,
|
||||
}
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@ function onLoad() {
|
|||
map.addSource('tegola-nidus', {
|
||||
'type': 'vector',
|
||||
'tiles': [
|
||||
'https://{{.Config.URLTegola}}/maps/nidus/{z}/{x}/{y}?organization_id={{.User.OrganizationID}}'
|
||||
'https://{{.Config.URLTegola}}/maps/nidus/{z}/{x}/{y}?organization_id={{.User.Organization.ID}}'
|
||||
]
|
||||
//'minzoom': 6,
|
||||
//'maxzoom': 14
|
||||
|
|
@ -172,7 +172,7 @@ body {
|
|||
<!-- Dashboard Header -->
|
||||
<div class="row mb-4">
|
||||
<div class="col-md-6">
|
||||
<h1>{{ .Org }} Dashboard</h1>
|
||||
<h1>{{ .User.Organization.Name }} Dashboard</h1>
|
||||
<p class="text-muted">Overview of mosquito control activities in your district</p>
|
||||
</div>
|
||||
<div class="col-md-6 text-md-end d-flex align-items-center justify-content-md-end">
|
||||
|
|
|
|||
|
|
@ -94,6 +94,10 @@ type Link struct {
|
|||
Href string
|
||||
Title string
|
||||
}
|
||||
type Organization struct {
|
||||
ID int
|
||||
Name string
|
||||
}
|
||||
type ServiceRequestSummary struct {
|
||||
Date time.Time
|
||||
Location string
|
||||
|
|
@ -103,6 +107,6 @@ type User struct {
|
|||
DisplayName string
|
||||
Initials string
|
||||
Notifications []notification.Notification
|
||||
OrganizationID int
|
||||
Organization Organization
|
||||
Username string
|
||||
}
|
||||
|
|
|
|||
|
|
@ -95,10 +95,15 @@ func contentForUser(ctx context.Context, user *models.User) (User, error) {
|
|||
if err != nil {
|
||||
return User{}, err
|
||||
}
|
||||
org := user.R.Organization
|
||||
return User{
|
||||
DisplayName: user.DisplayName,
|
||||
Initials: extractInitials(user.DisplayName),
|
||||
Notifications: notifications,
|
||||
Organization: Organization {
|
||||
ID: int(org.ID),
|
||||
Name: org.Name,
|
||||
},
|
||||
Username: user.Username,
|
||||
}, nil
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue