diff --git a/crm/docs/README.md b/crm/docs/README.md index d5330834a..1d679bb2a 100644 --- a/crm/docs/README.md +++ b/crm/docs/README.md @@ -208,6 +208,8 @@ CRM module definitions | Parameter | Type | Method | Description | Default | Required? | | --------- | ---- | ------ | ----------- | ------- | --------- | +| page | int | GET | Page number (0 based) | N/A | NO | +| perPage | int | GET | Returned items per page (default 50) | N/A | NO | | moduleID | uint64 | PATH | Module ID | N/A | YES | ## List/read contents from module section diff --git a/crm/docs/src/spec.json b/crm/docs/src/spec.json index 83fd28360..fe99d0bdb 100644 --- a/crm/docs/src/spec.json +++ b/crm/docs/src/spec.json @@ -220,6 +220,10 @@ "parameters": { "path": [ { "type": "uint64", "name": "moduleID", "required": true, "title": "Module ID" } + ], + "get": [ + { "name": "page", "type": "int", "required": false, "title": "Page number (0 based)" }, + { "name": "perPage", "type": "int", "required": false, "title": "Returned items per page (default 50)" } ] } }, diff --git a/crm/docs/src/spec/module.json b/crm/docs/src/spec/module.json index e92db1bf8..0fb282369 100644 --- a/crm/docs/src/spec/module.json +++ b/crm/docs/src/spec/module.json @@ -184,6 +184,20 @@ "Title": "List/read contents from module section", "Path": "/{module}/content", "Parameters": { + "get": [ + { + "name": "page", + "required": false, + "title": "Page number (0 based)", + "type": "int" + }, + { + "name": "perPage", + "required": false, + "title": "Returned items per page (default 50)", + "type": "int" + } + ], "path": [ { "name": "moduleID", diff --git a/crm/repository/content.go b/crm/repository/content.go index 89bb1e77b..b811e5984 100644 --- a/crm/repository/content.go +++ b/crm/repository/content.go @@ -2,6 +2,7 @@ package repository import ( "context" + "fmt" "strings" "time" @@ -18,7 +19,9 @@ type ( With(ctx context.Context, db *factory.DB) ContentRepository FindByID(id uint64) (*types.Content, error) - Find() ([]*types.Content, error) + + Find(moduleID uint64, page int, perPage int) ([]*types.Content, error) + Create(mod *types.Content) (*types.Content, error) Update(mod *types.Content) (*types.Content, error) DeleteByID(id uint64) error @@ -54,9 +57,21 @@ func (r *content) FindByID(id uint64) (*types.Content, error) { return mod, nil } -func (r *content) Find() ([]*types.Content, error) { +func (r *content) Find(moduleID uint64, page int, perPage int) ([]*types.Content, error) { mod := make([]*types.Content, 0) - return mod, r.db().Select(&mod, "SELECT * FROM crm_content WHERE deleted_at IS NULL ORDER BY id DESC") + if page < 0 { + page = 0 + } + if perPage <= 0 { + perPage = 50 + } + if perPage > 100 { + perPage = 100 + } + if perPage < 10 { + perPage = 10 + } + return mod, r.db().Select(&mod, fmt.Sprintf("SELECT * FROM crm_content WHERE module_id=? and deleted_at IS NULL ORDER BY id DESC LIMIT %d, %d", page, perPage), moduleID) } func (r *content) Create(mod *types.Content) (*types.Content, error) { diff --git a/crm/repository/content_test.go b/crm/repository/content_test.go index 89b3dea5d..f86306a72 100644 --- a/crm/repository/content_test.go +++ b/crm/repository/content_test.go @@ -93,7 +93,7 @@ func TestContent(t *testing.T) { // fetch all contents { - ms, err := repository.Find() + ms, err := repository.Find(module.ID, 0, 20) assert(t, err == nil, "Error when retrieving contents: %+v", err) assert(t, len(ms) == 1, "Expected one content, got %d", len(ms)) assert(t, ms[0].ModuleID == m.ModuleID, "Expected content module to match, %s != %s", m.ModuleID, ms[0].ModuleID) @@ -107,7 +107,7 @@ func TestContent(t *testing.T) { // fetch all contents { - ms, err := repository.Find() + ms, err := repository.Find(module.ID, 0, 20) assert(t, err == nil, "Error when retrieving contents: %+v", err) assert(t, len(ms) == 0, "Expected no content, got %d", len(ms)) } diff --git a/crm/rest/module.go b/crm/rest/module.go index 5615c67b7..c00143eab 100644 --- a/crm/rest/module.go +++ b/crm/rest/module.go @@ -51,7 +51,7 @@ func (s *Module) Edit(ctx context.Context, r *request.ModuleEdit) (interface{}, } func (s *Module) ContentList(ctx context.Context, r *request.ModuleContentList) (interface{}, error) { - return s.content.With(ctx).Find() + return s.content.With(ctx).Find(r.ModuleID, r.Page, r.PerPage) } func (s *Module) ContentRead(ctx context.Context, r *request.ModuleContentRead) (interface{}, error) { diff --git a/crm/rest/request/module.go b/crm/rest/request/module.go index 54eba451a..714223795 100644 --- a/crm/rest/request/module.go +++ b/crm/rest/request/module.go @@ -267,6 +267,8 @@ var _ RequestFiller = NewModuleDelete() // Module content/list request parameters type ModuleContentList struct { + Page int + PerPage int ModuleID uint64 } @@ -300,6 +302,14 @@ func (m *ModuleContentList) Fill(r *http.Request) error { post[name] = string(param[0]) } + if val, ok := get["page"]; ok { + + m.Page = parseInt(val) + } + if val, ok := get["perPage"]; ok { + + m.PerPage = parseInt(val) + } m.ModuleID = parseUInt64(chi.URLParam(r, "moduleID")) return err diff --git a/crm/rest/request/util.go b/crm/rest/request/util.go index 652e6b662..eb27222f2 100644 --- a/crm/rest/request/util.go +++ b/crm/rest/request/util.go @@ -17,13 +17,21 @@ func parseJSONText(s string) (types.JSONText, error) { return *result, err } +// parseInt parses a string to int +func parseInt(s string) int { + if s == "" { + return 0 + } + i, _ := strconv.Atoi(s) + return i +} + // parseInt64 parses an string to int64 func parseInt64(s string) int64 { if s == "" { return 0 } i, _ := strconv.ParseInt(s, 10, 64) - return i } diff --git a/crm/service/content.go b/crm/service/content.go index 80e5a60ba..a9a14a1d5 100644 --- a/crm/service/content.go +++ b/crm/service/content.go @@ -20,7 +20,8 @@ type ( With(ctx context.Context) ContentService FindByID(contentID uint64) (*types.Content, error) - Find() ([]*types.Content, error) + + Find(moduleID uint64, page int, perPage int) ([]*types.Content, error) Create(content *types.Content) (*types.Content, error) Update(content *types.Content) (*types.Content, error) @@ -45,8 +46,8 @@ func (s *content) FindByID(id uint64) (*types.Content, error) { return s.repository.FindByID(id) } -func (s *content) Find() ([]*types.Content, error) { - return s.repository.Find() +func (s *content) Find(moduleID uint64, page int, perPage int) ([]*types.Content, error) { + return s.repository.Find(moduleID, page, perPage) } func (s *content) Create(mod *types.Content) (*types.Content, error) { diff --git a/crm/types/types.go b/crm/types/types.go index 8f5f6704a..163dcfe6f 100644 --- a/crm/types/types.go +++ b/crm/types/types.go @@ -11,6 +11,7 @@ type ( Content struct { ID uint64 `json:"id" db:"id"` ModuleID uint64 `json:"moduleID" db:"module_id"` + Page *Page `json:"page,omitempty"` Fields types.JSONText `json:"fields,omitempty" db:"-"`