Initial commit: MyCrib API in Go

Complete rewrite of Django REST API to Go with:
- Gin web framework for HTTP routing
- GORM for database operations
- GoAdmin for admin panel
- Gorush integration for push notifications
- Redis for caching and job queues

Features implemented:
- User authentication (login, register, logout, password reset)
- Residence management (CRUD, sharing, share codes)
- Task management (CRUD, kanban board, completions)
- Contractor management (CRUD, specialties)
- Document management (CRUD, warranties)
- Notifications (preferences, push notifications)
- Subscription management (tiers, limits)

Infrastructure:
- Docker Compose for local development
- Database migrations and seed data
- Admin panel for data management

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Trey t
2025-11-26 20:07:16 -06:00
commit 1f12f3f62a
78 changed files with 13821 additions and 0 deletions

88
internal/admin/admin.go Normal file
View File

@@ -0,0 +1,88 @@
package admin
import (
"fmt"
_ "github.com/GoAdminGroup/go-admin/adapter/gin" // Gin adapter for GoAdmin
"github.com/GoAdminGroup/go-admin/engine"
"github.com/GoAdminGroup/go-admin/modules/config"
"github.com/GoAdminGroup/go-admin/modules/db"
"github.com/GoAdminGroup/go-admin/modules/language"
"github.com/GoAdminGroup/go-admin/plugins/admin"
"github.com/GoAdminGroup/go-admin/plugins/admin/modules/table"
"github.com/GoAdminGroup/go-admin/template"
"github.com/GoAdminGroup/go-admin/template/chartjs"
"github.com/GoAdminGroup/themes/adminlte"
"github.com/gin-gonic/gin"
appconfig "github.com/treytartt/mycrib-api/internal/config"
"github.com/treytartt/mycrib-api/internal/admin/tables"
)
// Setup initializes the GoAdmin panel
func Setup(r *gin.Engine, cfg *appconfig.Config) (*engine.Engine, error) {
eng := engine.Default()
// Register the AdminLTE theme
template.AddComp(chartjs.NewChart())
// Configure GoAdmin
adminConfig := config.Config{
Databases: config.DatabaseList{
"default": {
Host: cfg.Database.Host,
Port: fmt.Sprintf("%d", cfg.Database.Port),
User: cfg.Database.User,
Pwd: cfg.Database.Password,
Name: cfg.Database.Database,
MaxIdleConns: cfg.Database.MaxIdleConns,
MaxOpenConns: cfg.Database.MaxOpenConns,
Driver: db.DriverPostgresql,
},
},
UrlPrefix: "admin",
IndexUrl: "/",
Debug: cfg.Server.Debug,
Language: language.EN,
Theme: "adminlte",
Store: config.Store{
Path: "./uploads",
Prefix: "uploads",
},
Title: "MyCrib Admin",
Logo: "MyCrib",
MiniLogo: "MC",
BootstrapFilePath: "",
GoModFilePath: "",
ColorScheme: adminlte.ColorschemeSkinBlack,
Animation: config.PageAnimation{
Type: "fadeInUp",
},
}
// Add the admin plugin with generators
adminPlugin := admin.NewAdmin(GetTables())
// Initialize engine and add generators
if err := eng.AddConfig(&adminConfig).
AddGenerators(GetTables()).
AddPlugins(adminPlugin).
Use(r); err != nil {
return nil, err
}
// Add redirect for /admin to dashboard
r.GET("/admin", func(c *gin.Context) {
c.Redirect(302, "/admin/menu")
})
r.GET("/admin/", func(c *gin.Context) {
c.Redirect(302, "/admin/menu")
})
return eng, nil
}
// GetTables returns all table generators for the admin panel
func GetTables() table.GeneratorList {
return tables.Generators
}

View File

@@ -0,0 +1,73 @@
package tables
import (
"github.com/GoAdminGroup/go-admin/context"
"github.com/GoAdminGroup/go-admin/modules/db"
"github.com/GoAdminGroup/go-admin/plugins/admin/modules/table"
"github.com/GoAdminGroup/go-admin/template/types/form"
)
// GetContractorsTable returns the contractors table configuration
func GetContractorsTable(ctx *context.Context) table.Table {
contractors := table.NewDefaultTable(ctx, table.DefaultConfigWithDriver(db.DriverPostgresql))
info := contractors.GetInfo()
info.SetTable("task_contractor")
info.AddField("ID", "id", db.Int).FieldFilterable()
info.AddField("Name", "name", db.Varchar).FieldFilterable().FieldSortable()
info.AddField("Company", "company", db.Varchar).FieldFilterable()
info.AddField("Phone", "phone", db.Varchar).FieldFilterable()
info.AddField("Email", "email", db.Varchar).FieldFilterable()
info.AddField("Residence ID", "residence_id", db.Int).FieldFilterable()
info.AddField("Specialty ID", "specialty_id", db.Int).FieldFilterable()
info.AddField("Is Favorite", "is_favorite", db.Bool).FieldFilterable()
info.AddField("Notes", "notes", db.Text)
info.AddField("Created At", "created_at", db.Timestamp).FieldSortable()
info.AddField("Updated At", "updated_at", db.Timestamp).FieldSortable()
info.SetFilterFormLayout(form.LayoutThreeCol)
formList := contractors.GetForm()
formList.SetTable("task_contractor")
formList.AddField("ID", "id", db.Int, form.Default).FieldNotAllowAdd().FieldNotAllowEdit()
formList.AddField("Name", "name", db.Varchar, form.Text).FieldMust()
formList.AddField("Company", "company", db.Varchar, form.Text)
formList.AddField("Phone", "phone", db.Varchar, form.Text)
formList.AddField("Email", "email", db.Varchar, form.Email)
formList.AddField("Website", "website", db.Varchar, form.Url)
formList.AddField("Address", "address", db.Varchar, form.Text)
formList.AddField("City", "city", db.Varchar, form.Text)
formList.AddField("State", "state", db.Varchar, form.Text)
formList.AddField("Zip Code", "zip_code", db.Varchar, form.Text)
formList.AddField("Residence ID", "residence_id", db.Int, form.Number).FieldMust()
formList.AddField("Specialty ID", "specialty_id", db.Int, form.Number)
formList.AddField("Is Favorite", "is_favorite", db.Bool, form.Switch).FieldDefault("false")
formList.AddField("Notes", "notes", db.Text, form.TextArea)
return contractors
}
// GetContractorSpecialtiesTable returns the contractor specialties lookup table configuration
func GetContractorSpecialtiesTable(ctx *context.Context) table.Table {
specialties := table.NewDefaultTable(ctx, table.DefaultConfigWithDriver(db.DriverPostgresql))
info := specialties.GetInfo()
info.SetTable("task_contractorspecialty")
info.AddField("ID", "id", db.Int).FieldFilterable()
info.AddField("Name", "name", db.Varchar).FieldFilterable().FieldSortable()
info.AddField("Icon (iOS)", "icon_ios", db.Varchar)
info.AddField("Icon (Android)", "icon_android", db.Varchar)
info.AddField("Display Order", "display_order", db.Int).FieldSortable()
info.SetFilterFormLayout(form.LayoutThreeCol)
formList := specialties.GetForm()
formList.SetTable("task_contractorspecialty")
formList.AddField("ID", "id", db.Int, form.Default).FieldNotAllowAdd().FieldNotAllowEdit()
formList.AddField("Name", "name", db.Varchar, form.Text).FieldMust()
formList.AddField("Icon (iOS)", "icon_ios", db.Varchar, form.Text)
formList.AddField("Icon (Android)", "icon_android", db.Varchar, form.Text)
formList.AddField("Display Order", "display_order", db.Int, form.Number).FieldDefault("0")
return specialties
}

View File

@@ -0,0 +1,57 @@
package tables
import (
"github.com/GoAdminGroup/go-admin/context"
"github.com/GoAdminGroup/go-admin/modules/db"
"github.com/GoAdminGroup/go-admin/plugins/admin/modules/table"
"github.com/GoAdminGroup/go-admin/template/types"
"github.com/GoAdminGroup/go-admin/template/types/form"
)
// GetDocumentsTable returns the documents table configuration
func GetDocumentsTable(ctx *context.Context) table.Table {
documents := table.NewDefaultTable(ctx, table.DefaultConfigWithDriver(db.DriverPostgresql))
info := documents.GetInfo()
info.SetTable("task_document")
info.AddField("ID", "id", db.Int).FieldFilterable()
info.AddField("Title", "title", db.Varchar).FieldFilterable().FieldSortable()
info.AddField("Type", "document_type", db.Varchar).FieldFilterable()
info.AddField("Residence ID", "residence_id", db.Int).FieldFilterable()
info.AddField("File URL", "file_url", db.Varchar)
info.AddField("Is Active", "is_active", db.Bool).FieldFilterable()
info.AddField("Expiration Date", "expiration_date", db.Date).FieldSortable()
info.AddField("Created By ID", "created_by_id", db.Int).FieldFilterable()
info.AddField("Created At", "created_at", db.Timestamp).FieldSortable()
info.AddField("Updated At", "updated_at", db.Timestamp).FieldSortable()
info.SetFilterFormLayout(form.LayoutThreeCol)
formList := documents.GetForm()
formList.SetTable("task_document")
formList.AddField("ID", "id", db.Int, form.Default).FieldNotAllowAdd().FieldNotAllowEdit()
formList.AddField("Title", "title", db.Varchar, form.Text).FieldMust()
formList.AddField("Description", "description", db.Text, form.TextArea)
formList.AddField("Type", "document_type", db.Varchar, form.SelectSingle).
FieldOptions(types.FieldOptions{
{Value: "warranty", Text: "Warranty"},
{Value: "contract", Text: "Contract"},
{Value: "receipt", Text: "Receipt"},
{Value: "manual", Text: "Manual"},
{Value: "insurance", Text: "Insurance"},
{Value: "other", Text: "Other"},
})
formList.AddField("Residence ID", "residence_id", db.Int, form.Number).FieldMust()
formList.AddField("File URL", "file_url", db.Varchar, form.Url)
formList.AddField("Is Active", "is_active", db.Bool, form.Switch).FieldDefault("true")
formList.AddField("Expiration Date", "expiration_date", db.Date, form.Date)
formList.AddField("Purchase Date", "purchase_date", db.Date, form.Date)
formList.AddField("Purchase Amount", "purchase_amount", db.Decimal, form.Currency)
formList.AddField("Vendor", "vendor", db.Varchar, form.Text)
formList.AddField("Serial Number", "serial_number", db.Varchar, form.Text)
formList.AddField("Model Number", "model_number", db.Varchar, form.Text)
formList.AddField("Created By ID", "created_by_id", db.Int, form.Number)
formList.AddField("Notes", "notes", db.Text, form.TextArea)
return documents
}

View File

@@ -0,0 +1,51 @@
package tables
import (
"github.com/GoAdminGroup/go-admin/context"
"github.com/GoAdminGroup/go-admin/modules/db"
"github.com/GoAdminGroup/go-admin/plugins/admin/modules/table"
"github.com/GoAdminGroup/go-admin/template/types"
"github.com/GoAdminGroup/go-admin/template/types/form"
)
// GetNotificationsTable returns the notifications table configuration
func GetNotificationsTable(ctx *context.Context) table.Table {
notifications := table.NewDefaultTable(ctx, table.DefaultConfigWithDriver(db.DriverPostgresql))
info := notifications.GetInfo()
info.SetTable("notifications_notification")
info.AddField("ID", "id", db.Int).FieldFilterable()
info.AddField("User ID", "user_id", db.Int).FieldFilterable()
info.AddField("Title", "title", db.Varchar).FieldFilterable().FieldSortable()
info.AddField("Message", "message", db.Text)
info.AddField("Type", "notification_type", db.Varchar).FieldFilterable()
info.AddField("Is Read", "is_read", db.Bool).FieldFilterable()
info.AddField("Task ID", "task_id", db.Int).FieldFilterable()
info.AddField("Residence ID", "residence_id", db.Int).FieldFilterable()
info.AddField("Created At", "created_at", db.Timestamp).FieldSortable()
info.SetFilterFormLayout(form.LayoutThreeCol)
formList := notifications.GetForm()
formList.SetTable("notifications_notification")
formList.AddField("ID", "id", db.Int, form.Default).FieldNotAllowAdd().FieldNotAllowEdit()
formList.AddField("User ID", "user_id", db.Int, form.Number).FieldMust()
formList.AddField("Title", "title", db.Varchar, form.Text).FieldMust()
formList.AddField("Message", "message", db.Text, form.TextArea).FieldMust()
formList.AddField("Type", "notification_type", db.Varchar, form.SelectSingle).
FieldOptions(types.FieldOptions{
{Value: "task_assigned", Text: "Task Assigned"},
{Value: "task_completed", Text: "Task Completed"},
{Value: "task_due", Text: "Task Due"},
{Value: "task_overdue", Text: "Task Overdue"},
{Value: "residence_shared", Text: "Residence Shared"},
{Value: "system", Text: "System"},
})
formList.AddField("Is Read", "is_read", db.Bool, form.Switch).FieldDefault("false")
formList.AddField("Task ID", "task_id", db.Int, form.Number)
formList.AddField("Residence ID", "residence_id", db.Int, form.Number)
formList.AddField("Data JSON", "data", db.Text, form.TextArea)
formList.AddField("Action URL", "action_url", db.Varchar, form.Url)
return notifications
}

View File

@@ -0,0 +1,70 @@
package tables
import (
"github.com/GoAdminGroup/go-admin/context"
"github.com/GoAdminGroup/go-admin/modules/db"
"github.com/GoAdminGroup/go-admin/plugins/admin/modules/table"
"github.com/GoAdminGroup/go-admin/template/types/form"
)
// GetResidencesTable returns the residences table configuration
func GetResidencesTable(ctx *context.Context) table.Table {
residences := table.NewDefaultTable(ctx, table.DefaultConfigWithDriver(db.DriverPostgresql))
info := residences.GetInfo()
info.SetTable("residence_residence")
info.AddField("ID", "id", db.Int).FieldFilterable()
info.AddField("Name", "name", db.Varchar).FieldFilterable().FieldSortable()
info.AddField("Address", "address", db.Varchar).FieldFilterable()
info.AddField("City", "city", db.Varchar).FieldFilterable()
info.AddField("State", "state", db.Varchar).FieldFilterable()
info.AddField("Zip Code", "zip_code", db.Varchar).FieldFilterable()
info.AddField("Owner ID", "owner_id", db.Int).FieldFilterable()
info.AddField("Type ID", "residence_type_id", db.Int).FieldFilterable()
info.AddField("Is Active", "is_active", db.Bool).FieldFilterable()
info.AddField("Created At", "created_at", db.Timestamp).FieldSortable()
info.AddField("Updated At", "updated_at", db.Timestamp).FieldSortable()
info.SetFilterFormLayout(form.LayoutThreeCol)
formList := residences.GetForm()
formList.SetTable("residence_residence")
formList.AddField("ID", "id", db.Int, form.Default).FieldNotAllowAdd().FieldNotAllowEdit()
formList.AddField("Name", "name", db.Varchar, form.Text).FieldMust()
formList.AddField("Address", "address", db.Varchar, form.Text)
formList.AddField("City", "city", db.Varchar, form.Text)
formList.AddField("State", "state", db.Varchar, form.Text)
formList.AddField("Zip Code", "zip_code", db.Varchar, form.Text)
formList.AddField("Owner ID", "owner_id", db.Int, form.Number).FieldMust()
formList.AddField("Type ID", "residence_type_id", db.Int, form.Number)
formList.AddField("Is Active", "is_active", db.Bool, form.Switch).FieldDefault("true")
formList.AddField("Share Code", "share_code", db.Varchar, form.Text)
formList.AddField("Share Code Expires", "share_code_expires_at", db.Timestamp, form.Datetime)
return residences
}
// GetResidenceTypesTable returns the residence types lookup table configuration
func GetResidenceTypesTable(ctx *context.Context) table.Table {
types := table.NewDefaultTable(ctx, table.DefaultConfigWithDriver(db.DriverPostgresql))
info := types.GetInfo()
info.SetTable("residence_residencetype")
info.AddField("ID", "id", db.Int).FieldFilterable()
info.AddField("Name", "name", db.Varchar).FieldFilterable().FieldSortable()
info.AddField("Icon (iOS)", "icon_ios", db.Varchar)
info.AddField("Icon (Android)", "icon_android", db.Varchar)
info.AddField("Display Order", "display_order", db.Int).FieldSortable()
info.SetFilterFormLayout(form.LayoutThreeCol)
formList := types.GetForm()
formList.SetTable("residence_residencetype")
formList.AddField("ID", "id", db.Int, form.Default).FieldNotAllowAdd().FieldNotAllowEdit()
formList.AddField("Name", "name", db.Varchar, form.Text).FieldMust()
formList.AddField("Icon (iOS)", "icon_ios", db.Varchar, form.Text)
formList.AddField("Icon (Android)", "icon_android", db.Varchar, form.Text)
formList.AddField("Display Order", "display_order", db.Int, form.Number).FieldDefault("0")
return types
}

View File

@@ -0,0 +1,53 @@
package tables
import (
"github.com/GoAdminGroup/go-admin/context"
"github.com/GoAdminGroup/go-admin/modules/db"
"github.com/GoAdminGroup/go-admin/plugins/admin/modules/table"
"github.com/GoAdminGroup/go-admin/template/types"
"github.com/GoAdminGroup/go-admin/template/types/form"
)
// GetSubscriptionsTable returns the user subscriptions table configuration
func GetSubscriptionsTable(ctx *context.Context) table.Table {
subscriptions := table.NewDefaultTable(ctx, table.DefaultConfigWithDriver(db.DriverPostgresql))
info := subscriptions.GetInfo()
info.SetTable("subscription_usersubscription")
info.AddField("ID", "id", db.Int).FieldFilterable()
info.AddField("User ID", "user_id", db.Int).FieldFilterable()
info.AddField("Tier", "tier", db.Varchar).FieldFilterable()
info.AddField("Subscribed At", "subscribed_at", db.Timestamp).FieldSortable()
info.AddField("Expires At", "expires_at", db.Timestamp).FieldSortable()
info.AddField("Cancelled At", "cancelled_at", db.Timestamp).FieldSortable()
info.AddField("Auto Renew", "auto_renew", db.Bool).FieldFilterable()
info.AddField("Platform", "platform", db.Varchar).FieldFilterable()
info.AddField("Created At", "created_at", db.Timestamp).FieldSortable()
info.AddField("Updated At", "updated_at", db.Timestamp).FieldSortable()
info.SetFilterFormLayout(form.LayoutThreeCol)
formList := subscriptions.GetForm()
formList.SetTable("subscription_usersubscription")
formList.AddField("ID", "id", db.Int, form.Default).FieldNotAllowAdd().FieldNotAllowEdit()
formList.AddField("User ID", "user_id", db.Int, form.Number).FieldMust()
formList.AddField("Tier", "tier", db.Varchar, form.SelectSingle).
FieldOptions(types.FieldOptions{
{Value: "free", Text: "Free"},
{Value: "pro", Text: "Pro"},
}).FieldDefault("free")
formList.AddField("Subscribed At", "subscribed_at", db.Timestamp, form.Datetime)
formList.AddField("Expires At", "expires_at", db.Timestamp, form.Datetime)
formList.AddField("Cancelled At", "cancelled_at", db.Timestamp, form.Datetime)
formList.AddField("Auto Renew", "auto_renew", db.Bool, form.Switch).FieldDefault("true")
formList.AddField("Platform", "platform", db.Varchar, form.SelectSingle).
FieldOptions(types.FieldOptions{
{Value: "", Text: "None"},
{Value: "ios", Text: "iOS"},
{Value: "android", Text: "Android"},
})
formList.AddField("Apple Receipt Data", "apple_receipt_data", db.Text, form.TextArea)
formList.AddField("Google Purchase Token", "google_purchase_token", db.Text, form.TextArea)
return subscriptions
}

View File

@@ -0,0 +1,21 @@
package tables
import "github.com/GoAdminGroup/go-admin/plugins/admin/modules/table"
// Generators is a map of table generators
var Generators = map[string]table.Generator{
"users": GetUsersTable,
"residences": GetResidencesTable,
"tasks": GetTasksTable,
"task_completions": GetTaskCompletionsTable,
"contractors": GetContractorsTable,
"documents": GetDocumentsTable,
"notifications": GetNotificationsTable,
"user_subscriptions": GetSubscriptionsTable,
"task_categories": GetTaskCategoriesTable,
"task_priorities": GetTaskPrioritiesTable,
"task_statuses": GetTaskStatusesTable,
"task_frequencies": GetTaskFrequenciesTable,
"contractor_specialties": GetContractorSpecialtiesTable,
"residence_types": GetResidenceTypesTable,
}

View File

@@ -0,0 +1,187 @@
package tables
import (
"github.com/GoAdminGroup/go-admin/context"
"github.com/GoAdminGroup/go-admin/modules/db"
"github.com/GoAdminGroup/go-admin/plugins/admin/modules/table"
"github.com/GoAdminGroup/go-admin/template/types/form"
)
// GetTasksTable returns the tasks table configuration
func GetTasksTable(ctx *context.Context) table.Table {
tasks := table.NewDefaultTable(ctx, table.DefaultConfigWithDriver(db.DriverPostgresql))
info := tasks.GetInfo()
info.SetTable("task_task")
info.AddField("ID", "id", db.Int).FieldFilterable()
info.AddField("Title", "title", db.Varchar).FieldFilterable().FieldSortable()
info.AddField("Description", "description", db.Text)
info.AddField("Residence ID", "residence_id", db.Int).FieldFilterable()
info.AddField("Category ID", "category_id", db.Int).FieldFilterable()
info.AddField("Priority ID", "priority_id", db.Int).FieldFilterable()
info.AddField("Status ID", "status_id", db.Int).FieldFilterable()
info.AddField("Frequency ID", "frequency_id", db.Int).FieldFilterable()
info.AddField("Due Date", "due_date", db.Date).FieldFilterable().FieldSortable()
info.AddField("Created By ID", "created_by_id", db.Int).FieldFilterable()
info.AddField("Assigned To ID", "assigned_to_id", db.Int).FieldFilterable()
info.AddField("Is Recurring", "is_recurring", db.Bool).FieldFilterable()
info.AddField("Is Cancelled", "is_cancelled", db.Bool).FieldFilterable()
info.AddField("Is Archived", "is_archived", db.Bool).FieldFilterable()
info.AddField("Estimated Cost", "estimated_cost", db.Decimal)
info.AddField("Created At", "created_at", db.Timestamp).FieldSortable()
info.AddField("Updated At", "updated_at", db.Timestamp).FieldSortable()
info.SetFilterFormLayout(form.LayoutThreeCol)
formList := tasks.GetForm()
formList.SetTable("task_task")
formList.AddField("ID", "id", db.Int, form.Default).FieldNotAllowAdd().FieldNotAllowEdit()
formList.AddField("Title", "title", db.Varchar, form.Text).FieldMust()
formList.AddField("Description", "description", db.Text, form.TextArea)
formList.AddField("Residence ID", "residence_id", db.Int, form.Number).FieldMust()
formList.AddField("Category ID", "category_id", db.Int, form.Number)
formList.AddField("Priority ID", "priority_id", db.Int, form.Number)
formList.AddField("Status ID", "status_id", db.Int, form.Number)
formList.AddField("Frequency ID", "frequency_id", db.Int, form.Number)
formList.AddField("Due Date", "due_date", db.Date, form.Date)
formList.AddField("Created By ID", "created_by_id", db.Int, form.Number)
formList.AddField("Assigned To ID", "assigned_to_id", db.Int, form.Number)
formList.AddField("Contractor ID", "contractor_id", db.Int, form.Number)
formList.AddField("Is Recurring", "is_recurring", db.Bool, form.Switch).FieldDefault("false")
formList.AddField("Is Cancelled", "is_cancelled", db.Bool, form.Switch).FieldDefault("false")
formList.AddField("Is Archived", "is_archived", db.Bool, form.Switch).FieldDefault("false")
formList.AddField("Estimated Cost", "estimated_cost", db.Decimal, form.Currency)
formList.AddField("Notes", "notes", db.Text, form.TextArea)
return tasks
}
// GetTaskCompletionsTable returns the task completions table configuration
func GetTaskCompletionsTable(ctx *context.Context) table.Table {
completions := table.NewDefaultTable(ctx, table.DefaultConfigWithDriver(db.DriverPostgresql))
info := completions.GetInfo()
info.SetTable("task_taskcompletion")
info.AddField("ID", "id", db.Int).FieldFilterable()
info.AddField("Task ID", "task_id", db.Int).FieldFilterable()
info.AddField("User ID", "user_id", db.Int).FieldFilterable()
info.AddField("Completed At", "completed_at", db.Timestamp).FieldSortable()
info.AddField("Notes", "notes", db.Text)
info.AddField("Actual Cost", "actual_cost", db.Decimal)
info.AddField("Receipt URL", "receipt_url", db.Varchar)
info.AddField("Created At", "created_at", db.Timestamp).FieldSortable()
info.SetFilterFormLayout(form.LayoutThreeCol)
formList := completions.GetForm()
formList.SetTable("task_taskcompletion")
formList.AddField("ID", "id", db.Int, form.Default).FieldNotAllowAdd().FieldNotAllowEdit()
formList.AddField("Task ID", "task_id", db.Int, form.Number).FieldMust()
formList.AddField("User ID", "user_id", db.Int, form.Number).FieldMust()
formList.AddField("Completed At", "completed_at", db.Timestamp, form.Datetime)
formList.AddField("Notes", "notes", db.Text, form.TextArea)
formList.AddField("Actual Cost", "actual_cost", db.Decimal, form.Currency)
formList.AddField("Receipt URL", "receipt_url", db.Varchar, form.Url)
return completions
}
// GetTaskCategoriesTable returns the task categories lookup table configuration
func GetTaskCategoriesTable(ctx *context.Context) table.Table {
categories := table.NewDefaultTable(ctx, table.DefaultConfigWithDriver(db.DriverPostgresql))
info := categories.GetInfo()
info.SetTable("task_taskcategory")
info.AddField("ID", "id", db.Int).FieldFilterable()
info.AddField("Name", "name", db.Varchar).FieldFilterable().FieldSortable()
info.AddField("Icon (iOS)", "icon_ios", db.Varchar)
info.AddField("Icon (Android)", "icon_android", db.Varchar)
info.AddField("Color", "color", db.Varchar)
info.AddField("Display Order", "display_order", db.Int).FieldSortable()
info.SetFilterFormLayout(form.LayoutThreeCol)
formList := categories.GetForm()
formList.SetTable("task_taskcategory")
formList.AddField("ID", "id", db.Int, form.Default).FieldNotAllowAdd().FieldNotAllowEdit()
formList.AddField("Name", "name", db.Varchar, form.Text).FieldMust()
formList.AddField("Icon (iOS)", "icon_ios", db.Varchar, form.Text)
formList.AddField("Icon (Android)", "icon_android", db.Varchar, form.Text)
formList.AddField("Color", "color", db.Varchar, form.Color)
formList.AddField("Display Order", "display_order", db.Int, form.Number).FieldDefault("0")
return categories
}
// GetTaskPrioritiesTable returns the task priorities lookup table configuration
func GetTaskPrioritiesTable(ctx *context.Context) table.Table {
priorities := table.NewDefaultTable(ctx, table.DefaultConfigWithDriver(db.DriverPostgresql))
info := priorities.GetInfo()
info.SetTable("task_taskpriority")
info.AddField("ID", "id", db.Int).FieldFilterable()
info.AddField("Name", "name", db.Varchar).FieldFilterable().FieldSortable()
info.AddField("Level", "level", db.Int).FieldSortable()
info.AddField("Color", "color", db.Varchar)
info.AddField("Display Order", "display_order", db.Int).FieldSortable()
info.SetFilterFormLayout(form.LayoutThreeCol)
formList := priorities.GetForm()
formList.SetTable("task_taskpriority")
formList.AddField("ID", "id", db.Int, form.Default).FieldNotAllowAdd().FieldNotAllowEdit()
formList.AddField("Name", "name", db.Varchar, form.Text).FieldMust()
formList.AddField("Level", "level", db.Int, form.Number).FieldMust()
formList.AddField("Color", "color", db.Varchar, form.Color)
formList.AddField("Display Order", "display_order", db.Int, form.Number).FieldDefault("0")
return priorities
}
// GetTaskStatusesTable returns the task statuses lookup table configuration
func GetTaskStatusesTable(ctx *context.Context) table.Table {
statuses := table.NewDefaultTable(ctx, table.DefaultConfigWithDriver(db.DriverPostgresql))
info := statuses.GetInfo()
info.SetTable("task_taskstatus")
info.AddField("ID", "id", db.Int).FieldFilterable()
info.AddField("Name", "name", db.Varchar).FieldFilterable().FieldSortable()
info.AddField("Is Terminal", "is_terminal", db.Bool).FieldFilterable()
info.AddField("Color", "color", db.Varchar)
info.AddField("Display Order", "display_order", db.Int).FieldSortable()
info.SetFilterFormLayout(form.LayoutThreeCol)
formList := statuses.GetForm()
formList.SetTable("task_taskstatus")
formList.AddField("ID", "id", db.Int, form.Default).FieldNotAllowAdd().FieldNotAllowEdit()
formList.AddField("Name", "name", db.Varchar, form.Text).FieldMust()
formList.AddField("Is Terminal", "is_terminal", db.Bool, form.Switch).FieldDefault("false")
formList.AddField("Color", "color", db.Varchar, form.Color)
formList.AddField("Display Order", "display_order", db.Int, form.Number).FieldDefault("0")
return statuses
}
// GetTaskFrequenciesTable returns the task frequencies lookup table configuration
func GetTaskFrequenciesTable(ctx *context.Context) table.Table {
frequencies := table.NewDefaultTable(ctx, table.DefaultConfigWithDriver(db.DriverPostgresql))
info := frequencies.GetInfo()
info.SetTable("task_taskfrequency")
info.AddField("ID", "id", db.Int).FieldFilterable()
info.AddField("Name", "name", db.Varchar).FieldFilterable().FieldSortable()
info.AddField("Days", "days", db.Int).FieldSortable()
info.AddField("Display Order", "display_order", db.Int).FieldSortable()
info.SetFilterFormLayout(form.LayoutThreeCol)
formList := frequencies.GetForm()
formList.SetTable("task_taskfrequency")
formList.AddField("ID", "id", db.Int, form.Default).FieldNotAllowAdd().FieldNotAllowEdit()
formList.AddField("Name", "name", db.Varchar, form.Text).FieldMust()
formList.AddField("Days", "days", db.Int, form.Number)
formList.AddField("Display Order", "display_order", db.Int, form.Number).FieldDefault("0")
return frequencies
}

View File

@@ -0,0 +1,42 @@
package tables
import (
"github.com/GoAdminGroup/go-admin/context"
"github.com/GoAdminGroup/go-admin/modules/db"
"github.com/GoAdminGroup/go-admin/plugins/admin/modules/table"
"github.com/GoAdminGroup/go-admin/template/types/form"
)
// GetUsersTable returns the users table configuration
func GetUsersTable(ctx *context.Context) table.Table {
users := table.NewDefaultTable(ctx, table.DefaultConfigWithDriver(db.DriverPostgresql))
info := users.GetInfo()
info.SetTable("auth_user")
info.AddField("ID", "id", db.Int).FieldFilterable()
info.AddField("Email", "email", db.Varchar).FieldFilterable().FieldSortable()
info.AddField("First Name", "first_name", db.Varchar).FieldFilterable()
info.AddField("Last Name", "last_name", db.Varchar).FieldFilterable()
info.AddField("Is Active", "is_active", db.Bool).FieldFilterable()
info.AddField("Is Staff", "is_staff", db.Bool).FieldFilterable()
info.AddField("Is Superuser", "is_superuser", db.Bool).FieldFilterable()
info.AddField("Email Verified", "email_verified", db.Bool).FieldFilterable()
info.AddField("Date Joined", "date_joined", db.Timestamp).FieldSortable()
info.AddField("Last Login", "last_login", db.Timestamp).FieldSortable()
info.SetFilterFormLayout(form.LayoutThreeCol)
formList := users.GetForm()
formList.SetTable("auth_user")
formList.AddField("ID", "id", db.Int, form.Default).FieldNotAllowAdd().FieldNotAllowEdit()
formList.AddField("Email", "email", db.Varchar, form.Email).FieldMust()
formList.AddField("First Name", "first_name", db.Varchar, form.Text)
formList.AddField("Last Name", "last_name", db.Varchar, form.Text)
formList.AddField("Is Active", "is_active", db.Bool, form.Switch).FieldDefault("true")
formList.AddField("Is Staff", "is_staff", db.Bool, form.Switch).FieldDefault("false")
formList.AddField("Is Superuser", "is_superuser", db.Bool, form.Switch).FieldDefault("false")
formList.AddField("Email Verified", "email_verified", db.Bool, form.Switch).FieldDefault("false")
formList.AddField("Timezone", "timezone", db.Varchar, form.Text).FieldDefault("UTC")
return users
}