diff --git a/Featurecreep.md b/Featurecreep.md index 3189791ee13..0c6157b3fb9 100644 --- a/Featurecreep.md +++ b/Featurecreep.md @@ -29,7 +29,16 @@ Ab v0.3 können wir mit clients anfangen. #### v0.1 * [ ] Listen erstellen/bearbeiten/löschen + * [x] Ansehen + * [x] Übersicht + * [x] Einzelne liste mit allen todopunkten + * [x] Erstellen + * [x] Bearbeiten + * [ ] Löschen * [ ] Todopunkte hinzufügen/abhaken/löschen + * [x] Erstellen + * [ ] Bearbeiten (abhaken) + * [ ] Löschen #### v0.2 diff --git a/models/error.go b/models/error.go index 393ca928480..f560470d252 100644 --- a/models/error.go +++ b/models/error.go @@ -142,3 +142,16 @@ func IsErrListDoesNotExist(err error) bool { func (err ErrListDoesNotExist) Error() string { return fmt.Sprintf("List does not exist [ID: %d]", err.ID) } + +// ErrListItemCannotBeEmpty represents a "ErrListDoesNotExist" kind of error. Used if the list does not exist. +type ErrListItemCannotBeEmpty struct{} + +// IsErrListItemCannotBeEmpty checks if an error is a ErrListDoesNotExist. +func IsErrListItemCannotBeEmpty(err error) bool { + _, ok := err.(ErrListItemCannotBeEmpty) + return ok +} + +func (err ErrListItemCannotBeEmpty) Error() string { + return fmt.Sprintf("List item text cannot be empty.") +} diff --git a/models/list_items.go b/models/list_items.go index 3a9052b4159..7ab020664ac 100644 --- a/models/list_items.go +++ b/models/list_items.go @@ -13,7 +13,7 @@ type ListItem struct { Created int64 `xorm:"created" json:"created"` Updated int64 `xorm:"updated" json:"updated"` - CreatedBy User `xorm:"-"` + CreatedBy User `xorm:"-" json:"createdBy"` } // TableName returns the table name for listitems @@ -21,7 +21,46 @@ func (ListItem) TableName() string { return "items" } +// GetItemsByListID gets all todoitems for a list func GetItemsByListID(listID int64) (items []*ListItem, err error) { err = x.Where("list_id = ?", listID).Find(&items) + if err != nil { + return + } + + // Get all users and put them into the array + var userIDs []int64 + for _, i := range items { + found := false + for _, u := range userIDs { + if i.CreatedByID == u { + found = true + break + } + } + + if !found { + userIDs = append(userIDs, i.CreatedByID) + } + } + + var users []User + err = x.In("id", userIDs).Find(&users) + if err != nil { + return + } + + for in, item := range items { + for _, user := range users { + if item.CreatedByID == user.ID { + items[in].CreatedBy = user + break + } + } + + // obsfucate the user password + items[in].CreatedBy.Password = "" + } + return } diff --git a/models/list_items_create_update.go b/models/list_items_create_update.go new file mode 100644 index 00000000000..96313acb48b --- /dev/null +++ b/models/list_items_create_update.go @@ -0,0 +1,37 @@ +package models + +// CreateOrUpdateListItem adds or updates a todo item to a list +func CreateOrUpdateListItem(item *ListItem) (err error) { + + // Check if we have at least a text + if item.Text == "" { + return ErrListItemCannotBeEmpty{} + } + + // Check if the list exists + _, err = GetListByID(item.ListID) + if err != nil { + return + } + + // Check if the user exists + _, _, err = GetUserByID(item.CreatedBy.ID) + if err != nil { + return + } + item.CreatedByID = item.CreatedBy.ID + + if item.ID != 0 { + _, err = x.ID(item.ID).Update(item) + if err != nil { + return + } + } else { + _, err = x.Insert(item) + if err != nil { + return + } + } + + return +} diff --git a/models/lists.go b/models/lists.go index 2bca618fd6a..6c59b524468 100644 --- a/models/lists.go +++ b/models/lists.go @@ -10,7 +10,7 @@ type List struct { Created int64 `xorm:"created" json:"created"` Updated int64 `xorm:"updated" json:"updated"` - Items []*ListItem `xorm:"-"` + Items []*ListItem `xorm:"-" json:"items"` } // GetListByID returns a list by its ID @@ -32,6 +32,7 @@ func GetListByID(id int64) (list List, err error) { } list.Owner = user + list.Owner.Password = "" items, err := GetItemsByListID(list.ID) if err != nil { diff --git a/routes/api/v1/list_item_add_update.go b/routes/api/v1/list_item_add_update.go new file mode 100644 index 00000000000..17e8e6b1a7d --- /dev/null +++ b/routes/api/v1/list_item_add_update.go @@ -0,0 +1,50 @@ +package v1 + +import ( + "git.kolaente.de/konrad/list/models" + "github.com/labstack/echo" + "net/http" + "strconv" +) + +func AddOrUpdateListItem(c echo.Context) error { + // Get the list item + var listItem *models.ListItem + + if err := c.Bind(&listItem); err != nil { + return c.JSON(http.StatusBadRequest, models.Message{"No list model provided."}) + } + + // Get the list ID + id := c.Param("id") + // Make int + listID, err := strconv.ParseInt(id, 10, 64) + if err != nil { + return c.JSON(http.StatusBadRequest, models.Message{"Invalid ID."}) + } + listItem.ListID = listID + + // Set the user + user, err := models.GetCurrentUser(c) + if err != nil { + return c.JSON(http.StatusInternalServerError, models.Message{"An error occured."}) + } + listItem.CreatedBy = user + + err = models.CreateOrUpdateListItem(listItem) + if err != nil { + if models.IsErrListDoesNotExist(err) { + return c.JSON(http.StatusBadRequest, models.Message{"The list does not exist."}) + } + if models.IsErrListItemCannotBeEmpty(err) { + return c.JSON(http.StatusBadRequest, models.Message{"You must provide at least a list item text."}) + } + if models.IsErrUserDoesNotExist(err) { + return c.JSON(http.StatusBadRequest, models.Message{"The user does not exist."}) + } + + return c.JSON(http.StatusInternalServerError, models.Message{"An error occured."}) + } + + return c.JSON(http.StatusOK, listItem) +} diff --git a/routes/api/v1/list_show.go b/routes/api/v1/list_show.go new file mode 100644 index 00000000000..2cf7cb0b789 --- /dev/null +++ b/routes/api/v1/list_show.go @@ -0,0 +1,32 @@ +package v1 + +import ( + "git.kolaente.de/konrad/list/models" + "github.com/labstack/echo" + "net/http" + "strconv" +) + +// AddOrUpdateList Adds or updates a new list +func GetListByID(c echo.Context) error { + // Check if we have our ID + id := c.Param("id") + // Make int + listID, err := strconv.ParseInt(id, 10, 64) + + if err != nil { + return c.JSON(http.StatusBadRequest, models.Message{"Invalid ID."}) + } + + // Get the list + list, err := models.GetListByID(listID) + if err != nil { + if models.IsErrListDoesNotExist(err) { + return c.JSON(http.StatusBadRequest, models.Message{"The list does not exist."}) + } + + return c.JSON(http.StatusInternalServerError, models.Message{"An error occured."}) + } + + return c.JSON(http.StatusOK, list) +} diff --git a/routes/api/v1/lists_list.go b/routes/api/v1/lists_list.go index 2789a8e557a..62407d93466 100644 --- a/routes/api/v1/lists_list.go +++ b/routes/api/v1/lists_list.go @@ -16,6 +16,11 @@ func GetListsByUser(c echo.Context) error { allLists, err := models.GetListsByUser(¤tUser) if err != nil { + + if models.IsErrListDoesNotExist(err) { + + } + return c.JSON(http.StatusInternalServerError, models.Message{"Could not get lists."}) } diff --git a/routes/routes.go b/routes/routes.go index 44ae20cecda..16ff3432dc0 100644 --- a/routes/routes.go +++ b/routes/routes.go @@ -55,5 +55,7 @@ func RegisterRoutes(e *echo.Echo) { a.PUT("/lists", apiv1.AddOrUpdateList) a.GET("/lists", apiv1.GetListsByUser) + a.GET("/lists/:id", apiv1.GetListByID) a.POST("/lists/:id", apiv1.AddOrUpdateList) + a.PUT("/lists/:id", apiv1.AddOrUpdateListItem) }