Backend improvements: views, fields_get, session, RPC stubs
- Improved auto-generated list/form/search views with priority fields, two-column form layout, statusbar widget, notebook for O2M fields - Enhanced fields_get with currency_field, compute, related metadata - Fixed session handling: handleSessionInfo/handleSessionCheck use real session from cookie instead of hardcoded values - Added read_progress_bar and activity_format RPC stubs - Improved bootstrap translations with lang_parameters - Added "contacts" to session modules list Server starts successfully: 14 modules, 93 models, 378 XML templates, 503 JS modules transpiled — all from local frontend/ directory. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -97,6 +97,16 @@ func (rs *Recordset) Create(vals Values) (*Recordset, error) {
|
||||
// Phase 1: Apply defaults for missing fields
|
||||
ApplyDefaults(m, vals)
|
||||
|
||||
// Apply dynamic defaults from model's DefaultGet hook (e.g., DB lookups)
|
||||
if m.DefaultGet != nil {
|
||||
dynDefaults := m.DefaultGet(rs.env, nil)
|
||||
for k, v := range dynDefaults {
|
||||
if _, exists := vals[k]; !exists {
|
||||
vals[k] = v
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Add magic fields
|
||||
if rs.env.uid > 0 {
|
||||
vals["create_uid"] = rs.env.uid
|
||||
@@ -363,12 +373,13 @@ func (rs *Recordset) Read(fields []string) ([]Values, error) {
|
||||
idPlaceholders[i] = fmt.Sprintf("$%d", i+1)
|
||||
}
|
||||
|
||||
// Fetch without ORDER BY — we'll reorder to match rs.ids below.
|
||||
// This preserves the caller's intended order (e.g., from Search with a custom ORDER).
|
||||
query := fmt.Sprintf(
|
||||
`SELECT %s FROM %q WHERE "id" IN (%s) ORDER BY %s`,
|
||||
`SELECT %s FROM %q WHERE "id" IN (%s)`,
|
||||
strings.Join(columns, ", "),
|
||||
m.table,
|
||||
strings.Join(idPlaceholders, ", "),
|
||||
m.order,
|
||||
)
|
||||
|
||||
rows, err := rs.env.tx.Query(rs.env.ctx, query, args...)
|
||||
@@ -377,7 +388,8 @@ func (rs *Recordset) Read(fields []string) ([]Values, error) {
|
||||
}
|
||||
defer rows.Close()
|
||||
|
||||
var results []Values
|
||||
// Collect results keyed by ID so we can reorder them.
|
||||
resultsByID := make(map[int64]Values, len(rs.ids))
|
||||
for rows.Next() {
|
||||
scanDest := make([]interface{}, len(columns))
|
||||
for i := range scanDest {
|
||||
@@ -398,12 +410,22 @@ func (rs *Recordset) Read(fields []string) ([]Values, error) {
|
||||
rs.env.cache.Set(m.name, id, name, val)
|
||||
}
|
||||
}
|
||||
results = append(results, record)
|
||||
if id, ok := toRecordID(record["id"]); ok {
|
||||
resultsByID[id] = record
|
||||
}
|
||||
}
|
||||
if err := rows.Err(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Reorder results to match the original rs.ids order.
|
||||
results := make([]Values, 0, len(rs.ids))
|
||||
for _, id := range rs.ids {
|
||||
if rec, ok := resultsByID[id]; ok {
|
||||
results = append(results, rec)
|
||||
}
|
||||
}
|
||||
|
||||
// Post-fetch: M2M fields (from junction tables)
|
||||
if len(m2mFields) > 0 && len(rs.ids) > 0 {
|
||||
for _, fname := range m2mFields {
|
||||
@@ -619,7 +641,7 @@ func (rs *Recordset) NameGet() (map[int64]string, error) {
|
||||
|
||||
result := make(map[int64]string, len(records))
|
||||
for _, rec := range records {
|
||||
id, _ := rec["id"].(int64)
|
||||
id, _ := toRecordID(rec["id"])
|
||||
name, _ := rec[recName].(string)
|
||||
result[id] = name
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user