feat: custom content type icons, built-in types, user lookup
This commit is contained in:
1 parent
e6e088c963
commit
73a75d5cb9
31 files changed
+1611
-36
No files matched your search
@@ -14,6 +14,7 @@ type CreateContentTypeUseCase struct {
|
||||
type CreateContentTypeCommand struct {
|
||||
Key string
|
||||
Name string
|
||||
Icon *string
|
||||
Fields []contenttype.Field
|
||||
}
|
||||
|
||||
@@ -28,6 +29,10 @@ func (u *CreateContentTypeUseCase) Create(command CreateContentTypeCommand) (con
|
||||
if err := contenttype.ValidateName(command.Name); err != nil {
|
||||
return contenttype.ContentType{}, err
|
||||
}
|
||||
icon, err := contenttype.ValidateIcon(command.Icon)
|
||||
if err != nil {
|
||||
return contenttype.ContentType{}, err
|
||||
}
|
||||
fields, err := contenttype.ValidateFields(command.Fields)
|
||||
if err != nil {
|
||||
return contenttype.ContentType{}, err
|
||||
@@ -39,6 +44,7 @@ func (u *CreateContentTypeUseCase) Create(command CreateContentTypeCommand) (con
|
||||
return u.contentTypes.Create(contenttype.ContentType{
|
||||
Key: command.Key,
|
||||
Name: command.Name,
|
||||
Icon: icon,
|
||||
Fields: fields,
|
||||
CreatedAt: created,
|
||||
UpdatedAt: created,
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
package useCases
|
||||
|
||||
import "RenewCMS/internal/domain/builtintype"
|
||||
|
||||
type GetBuiltinTypeUseCase struct{}
|
||||
|
||||
func NewGetBuiltinTypeUseCase() *GetBuiltinTypeUseCase {
|
||||
return &GetBuiltinTypeUseCase{}
|
||||
}
|
||||
|
||||
func (u *GetBuiltinTypeUseCase) Get(key string) (builtintype.Type, error) {
|
||||
return builtintype.Find(key)
|
||||
}
|
||||
@@ -5,7 +5,6 @@ import (
|
||||
"RenewCMS/internal/domain/user"
|
||||
"errors"
|
||||
"sort"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
@@ -62,7 +61,7 @@ func (l *ListAPIKeysUseCase) creatorNamesFor(requester user.User, keys []apikey.
|
||||
if requester.Role != user.RoleOwner {
|
||||
return names, nil
|
||||
}
|
||||
names[requester.ID] = displayNameOrUsername(requester)
|
||||
names[requester.ID] = requester.NameOrUsername()
|
||||
for _, key := range keys {
|
||||
if _, resolved := names[key.UserID]; resolved {
|
||||
continue
|
||||
@@ -75,18 +74,11 @@ func (l *ListAPIKeysUseCase) creatorNamesFor(requester user.User, keys []apikey.
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
names[key.UserID] = displayNameOrUsername(creator)
|
||||
names[key.UserID] = creator.NameOrUsername()
|
||||
}
|
||||
return names, nil
|
||||
}
|
||||
|
||||
func displayNameOrUsername(account user.User) string {
|
||||
if trimmed := strings.TrimSpace(account.DisplayName); trimmed != "" {
|
||||
return trimmed
|
||||
}
|
||||
return account.Username
|
||||
}
|
||||
|
||||
func (l *ListAPIKeysUseCase) keysVisibleTo(requester user.User) ([]apikey.APIKey, error) {
|
||||
if requester.Role == user.RoleOwner {
|
||||
return l.apiKeyRepository.ListAll()
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
package useCases
|
||||
|
||||
import "RenewCMS/internal/domain/builtintype"
|
||||
|
||||
type ListBuiltinTypesUseCase struct{}
|
||||
|
||||
func NewListBuiltinTypesUseCase() *ListBuiltinTypesUseCase {
|
||||
return &ListBuiltinTypesUseCase{}
|
||||
}
|
||||
|
||||
func (u *ListBuiltinTypesUseCase) List() []builtintype.Type {
|
||||
return builtintype.Catalogue()
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
package useCases
|
||||
|
||||
import (
|
||||
"RenewCMS/internal/domain/user"
|
||||
"sort"
|
||||
)
|
||||
|
||||
type LookupUserNamesUseCase struct {
|
||||
users user.Repository
|
||||
}
|
||||
|
||||
type UserName struct {
|
||||
ID uint32
|
||||
DisplayName string
|
||||
}
|
||||
|
||||
func NewLookupUserNamesUseCase(users user.Repository) *LookupUserNamesUseCase {
|
||||
return &LookupUserNamesUseCase{users}
|
||||
}
|
||||
|
||||
func (u *LookupUserNamesUseCase) Lookup(ids []uint32) ([]UserName, error) {
|
||||
distinct := distinctIDs(ids)
|
||||
if len(distinct) == 0 || len(distinct) > user.MaxLookupIDs {
|
||||
return nil, user.ErrInvalidLookup
|
||||
}
|
||||
found, err := u.users.FindByIDs(distinct)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
sort.Slice(found, func(i, j int) bool { return found[i].ID < found[j].ID })
|
||||
names := make([]UserName, 0, len(found))
|
||||
for _, record := range found {
|
||||
names = append(names, UserName{ID: record.ID, DisplayName: record.NameOrUsername()})
|
||||
}
|
||||
return names, nil
|
||||
}
|
||||
|
||||
func distinctIDs(ids []uint32) []uint32 {
|
||||
seen := make(map[uint32]bool, len(ids))
|
||||
distinct := make([]uint32, 0, len(ids))
|
||||
for _, id := range ids {
|
||||
if !seen[id] {
|
||||
seen[id] = true
|
||||
distinct = append(distinct, id)
|
||||
}
|
||||
}
|
||||
return distinct
|
||||
}
|
||||
@@ -15,6 +15,7 @@ type UpdateContentTypeUseCase struct {
|
||||
type UpdateContentTypeCommand struct {
|
||||
Key string
|
||||
Name string
|
||||
Icon *string
|
||||
Fields []contenttype.Field
|
||||
}
|
||||
|
||||
@@ -30,6 +31,10 @@ func (u *UpdateContentTypeUseCase) Update(command UpdateContentTypeCommand) (con
|
||||
if err := contenttype.ValidateName(command.Name); err != nil {
|
||||
return contenttype.ContentType{}, err
|
||||
}
|
||||
icon, err := contenttype.ValidateIcon(command.Icon)
|
||||
if err != nil {
|
||||
return contenttype.ContentType{}, err
|
||||
}
|
||||
fields, err := contenttype.ValidateFields(command.Fields)
|
||||
if err != nil {
|
||||
return contenttype.ContentType{}, err
|
||||
@@ -44,6 +49,7 @@ func (u *UpdateContentTypeUseCase) Update(command UpdateContentTypeCommand) (con
|
||||
}
|
||||
}
|
||||
current.Name = command.Name
|
||||
current.Icon = icon
|
||||
current.Fields = fields
|
||||
current.UpdatedAt = u.now()
|
||||
return u.contentTypes.Update(current)
|
||||
|
||||
Reference in new issue
Block a user