feat: site languages, setup and site URL settings
This commit is contained in:
1 parent
0806733d5c
commit
d9158025d4
106 files changed
+10184
-56
No files matched your search
@@ -0,0 +1,128 @@
|
||||
package useCases
|
||||
|
||||
import (
|
||||
"RenewCMS/internal/domain/audit"
|
||||
"RenewCMS/internal/domain/localization"
|
||||
"RenewCMS/internal/domain/transaction"
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"slices"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type UpdateSiteLanguagesUseCase struct {
|
||||
transactor transaction.Transactor
|
||||
recorder audit.Recorder
|
||||
}
|
||||
|
||||
type SiteLanguageEntry struct {
|
||||
Lang string
|
||||
Enabled bool
|
||||
SocialLocale *string
|
||||
}
|
||||
|
||||
type UpdateSiteLanguagesCommand struct {
|
||||
Key string
|
||||
Revision string
|
||||
Default string
|
||||
Languages []SiteLanguageEntry
|
||||
}
|
||||
|
||||
func NewUpdateSiteLanguagesUseCase(transactor transaction.Transactor, recorder audit.Recorder) *UpdateSiteLanguagesUseCase {
|
||||
return &UpdateSiteLanguagesUseCase{transactor, recorder}
|
||||
}
|
||||
|
||||
func (u *UpdateSiteLanguagesUseCase) Update(ctx context.Context, command UpdateSiteLanguagesCommand) (localization.View, error) {
|
||||
event := audit.NewEvent(audit.ActionSiteLanguagesEdit, audit.CategorySites)
|
||||
var view localization.View
|
||||
var before []localization.Row
|
||||
var after []localization.Row
|
||||
err := u.transactor.Run(ctx, func(tx transaction.Repositories) error {
|
||||
found, err := tx.Sites.GetByKey(command.Key)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
event.Target = siteTarget(found)
|
||||
if err := tx.Sites.LockSite(found.ID); err != nil {
|
||||
return err
|
||||
}
|
||||
before, err = tx.Localization.Rows(found.ID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if localization.NeedsSetup(before) {
|
||||
return localization.ErrSetupRequired
|
||||
}
|
||||
if localization.Revision(before) != command.Revision {
|
||||
return localization.ErrLanguagesChanged
|
||||
}
|
||||
counts, err := tx.Localization.VersionCounts(found.ID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
after, err = localization.Plan(before, counts, command.change())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if !localization.SameRows(before, after) {
|
||||
if err := tx.Localization.Replace(found.ID, after); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
view, err = readSiteLanguages(tx.Localization, found.ID)
|
||||
return err
|
||||
})
|
||||
if errors.Is(err, transaction.ErrLockContention) {
|
||||
err = fmt.Errorf("%w: %w", localization.ErrLanguagesChanged, err)
|
||||
}
|
||||
if err != nil {
|
||||
recordFailure(ctx, u.recorder, event, err)
|
||||
return localization.View{}, err
|
||||
}
|
||||
if changes := languageChanges(before, after); len(changes) > 0 {
|
||||
event.Changes = changes
|
||||
u.recorder.Record(ctx, event)
|
||||
}
|
||||
return view, nil
|
||||
}
|
||||
|
||||
func languageChanges(before []localization.Row, after []localization.Row) []audit.Change {
|
||||
changes := []audit.Change{}
|
||||
changes = audit.AppendTextChange(changes, audit.FieldDefaultLanguage, defaultTag(before), defaultTag(after))
|
||||
return audit.AppendTextChange(changes, audit.FieldLanguages, languagesLabel(before), languagesLabel(after))
|
||||
}
|
||||
|
||||
func defaultTag(rows []localization.Row) string {
|
||||
for _, row := range rows {
|
||||
if row.IsDefault {
|
||||
return row.Tag
|
||||
}
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func languagesLabel(rows []localization.Row) string {
|
||||
ordered := slices.Clone(rows)
|
||||
slices.SortFunc(ordered, func(left localization.Row, right localization.Row) int { return strings.Compare(left.Tag, right.Tag) })
|
||||
labels := make([]string, 0, len(ordered))
|
||||
for _, row := range ordered {
|
||||
label := row.Tag
|
||||
if !row.Enabled {
|
||||
label += " (off)"
|
||||
}
|
||||
if row.SocialLocale != nil {
|
||||
label += " [" + *row.SocialLocale + "]"
|
||||
}
|
||||
labels = append(labels, label)
|
||||
}
|
||||
return strings.Join(labels, ", ")
|
||||
}
|
||||
|
||||
func (c UpdateSiteLanguagesCommand) change() localization.Change {
|
||||
entries := make([]localization.Entry, 0, len(c.Languages))
|
||||
for _, entry := range c.Languages {
|
||||
entries = append(entries, localization.Entry{Tag: entry.Lang, Enabled: entry.Enabled, SocialLocale: entry.SocialLocale})
|
||||
}
|
||||
return localization.Change{Default: c.Default, Languages: entries}
|
||||
}
|
||||
Reference in new issue
Block a user