feat: edit and delete settings history rows
Backend:
- SettingsStore: Add GetByID, Update, Delete, Count methods
- SettingsService: Add UpdateSettings (validates same rules as Upsert),
DeleteSettings (guards against deleting the last row → 409)
- New sentinels: ErrSettingsNotFound, ErrLastSettingsRow
- Handler: PUT /api/settings/history/{id} → 200 updated row
DELETE /api/settings/history/{id} → 204 / 404 / 409
Frontend:
- API client: settings.update(id, body) and settings.delete(id)
- Settings page: history table gains edit (pencil) and delete (×) buttons
- Inline edit form expands in place within the table row
- Delete button disabled and hint shown when only one row remains
- maskLabel() helper shows workday names instead of raw bitmask
- After save/delete: full reload to reflect changes in 'current' section
This commit is contained in:
@@ -71,6 +71,37 @@ func (s *SettingsStore) Insert(ctx context.Context, set *domain.Settings) error
|
||||
return nil
|
||||
}
|
||||
|
||||
// Update overwrites an existing settings row by ID.
|
||||
func (s *SettingsStore) Update(ctx context.Context, set *domain.Settings) error {
|
||||
_, err := s.db.ExecContext(ctx,
|
||||
`UPDATE settings_history
|
||||
SET effective_from=?, hours_per_week=?, workdays_mask=?, timezone=?
|
||||
WHERE id=?`,
|
||||
set.EffectiveFrom, set.HoursPerWeek, set.WorkdaysMask, set.Timezone, set.ID)
|
||||
return err
|
||||
}
|
||||
|
||||
// Delete removes a settings row by ID.
|
||||
func (s *SettingsStore) Delete(ctx context.Context, id int64) error {
|
||||
_, err := s.db.ExecContext(ctx, `DELETE FROM settings_history WHERE id=?`, id)
|
||||
return err
|
||||
}
|
||||
|
||||
// Count returns the total number of settings rows.
|
||||
func (s *SettingsStore) Count(ctx context.Context) (int, error) {
|
||||
var n int
|
||||
err := s.db.QueryRowContext(ctx, `SELECT COUNT(*) FROM settings_history`).Scan(&n)
|
||||
return n, err
|
||||
}
|
||||
|
||||
// GetByID returns a single settings row by ID.
|
||||
func (s *SettingsStore) GetByID(ctx context.Context, id int64) (*domain.Settings, error) {
|
||||
row := s.db.QueryRowContext(ctx,
|
||||
`SELECT id, effective_from, hours_per_week, workdays_mask, timezone, created_at
|
||||
FROM settings_history WHERE id=?`, id)
|
||||
return scanSettings(row)
|
||||
}
|
||||
|
||||
func scanSettings(row *sql.Row) (*domain.Settings, error) {
|
||||
var s domain.Settings
|
||||
err := row.Scan(&s.ID, &s.EffectiveFrom, &s.HoursPerWeek, &s.WorkdaysMask, &s.Timezone, &s.CreatedAt)
|
||||
|
||||
Reference in New Issue
Block a user