feat: relation field and picker
This commit is contained in:
1 parent
b45c99be3b
commit
37a77c9c22
92 files changed
+6826
-80
No files matched your search
@@ -92,6 +92,8 @@ func writeContentTypeError(w http.ResponseWriter, err error) {
|
||||
http.Error(w, apperr.ContentTypeKeyTakenErrorMessage, http.StatusConflict)
|
||||
case errors.Is(err, domain.ErrHasEntries):
|
||||
http.Error(w, apperr.ContentTypeHasEntriesErrorMessage, http.StatusConflict)
|
||||
case errors.Is(err, domain.ErrReferenced):
|
||||
http.Error(w, apperr.ContentTypeReferencedErrorMessage, http.StatusConflict)
|
||||
case errors.Is(err, domain.ErrSchemaIncompatible):
|
||||
http.Error(w, apperr.SchemaIncompatibleErrorMessage, http.StatusConflict)
|
||||
case errors.Is(err, domain.ErrInvalidName):
|
||||
|
||||
@@ -43,6 +43,49 @@ type entryResponse struct {
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
UpdatedAt time.Time `json:"updated_at"`
|
||||
Media map[string]any `json:"media"`
|
||||
Relations map[string]any `json:"relations"`
|
||||
}
|
||||
|
||||
type firstFieldBody struct {
|
||||
Key string `json:"key"`
|
||||
Type contenttype.FieldType `json:"type"`
|
||||
Value any `json:"value"`
|
||||
}
|
||||
|
||||
type relationBody struct {
|
||||
ID uint32 `json:"id"`
|
||||
ContentType string `json:"content_type"`
|
||||
FirstField firstFieldBody `json:"first_field"`
|
||||
}
|
||||
|
||||
type missingRelationBody struct {
|
||||
ID uint32 `json:"id"`
|
||||
Missing bool `json:"missing"`
|
||||
}
|
||||
|
||||
func toRelationItem(item useCases.EntryRelation) any {
|
||||
if item.Missing {
|
||||
return missingRelationBody{ID: item.ID, Missing: true}
|
||||
}
|
||||
return relationBody{ID: item.ID, ContentType: item.ContentType, FirstField: firstFieldBody{Key: item.FirstField.Key, Type: item.FirstField.Type, Value: item.FirstField.Value}}
|
||||
}
|
||||
|
||||
func toRelationsResponse(relations map[string]useCases.EntryRelations) map[string]any {
|
||||
body := make(map[string]any, len(relations))
|
||||
for key, held := range relations {
|
||||
if !held.Many {
|
||||
if len(held.Items) > 0 {
|
||||
body[key] = toRelationItem(held.Items[0])
|
||||
}
|
||||
continue
|
||||
}
|
||||
items := make([]any, 0, len(held.Items))
|
||||
for _, item := range held.Items {
|
||||
items = append(items, toRelationItem(item))
|
||||
}
|
||||
body[key] = items
|
||||
}
|
||||
return body
|
||||
}
|
||||
|
||||
type mediaBody struct {
|
||||
@@ -81,6 +124,7 @@ func toResponse(typed useCases.TypedEntry) entryResponse {
|
||||
CreatedAt: typed.CreatedAt,
|
||||
UpdatedAt: typed.UpdatedAt,
|
||||
Media: toMediaResponse(typed.Media),
|
||||
Relations: toRelationsResponse(typed.Relations),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -181,7 +225,7 @@ func (h *Handler) List(w http.ResponseWriter, r *http.Request) {
|
||||
http.Error(w, apperr.BodyErrorMessage, http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
page, err := h.ListUseCase.ListPage(useCases.ListEntriesCommand{ContentTypeKey: chi.URLParam(r, "key"), Page: query.Page, Size: query.Size, Sort: query.Sort})
|
||||
page, err := h.ListUseCase.ListPage(useCases.ListEntriesCommand{ContentTypeKey: chi.URLParam(r, "key"), Page: query.Page, Size: query.Size, Sort: query.Sort, Query: r.URL.Query().Get("q")})
|
||||
if err != nil {
|
||||
writeEntryError(w, err)
|
||||
return
|
||||
|
||||
@@ -92,6 +92,7 @@ const SlugSuggestionHeader = "X-Slug-Suggestion"
|
||||
const ContentTypeNotFoundErrorMessage = "content_type_not_found"
|
||||
const ContentTypeKeyTakenErrorMessage = "content_type_key_taken"
|
||||
const ContentTypeHasEntriesErrorMessage = "content_type_has_entries"
|
||||
const ContentTypeReferencedErrorMessage = "content_type_referenced"
|
||||
const InvalidContentTypeKeyErrorMessage = "invalid_content_type_key"
|
||||
const InvalidIconErrorMessage = "invalid_icon"
|
||||
const BuiltinTypeNotFoundErrorMessage = "builtin_type_not_found"
|
||||
|
||||
Reference in new issue
Block a user