diff --git a/server/command.go b/server/command.go index c3c04857..01dfb1c3 100644 --- a/server/command.go +++ b/server/command.go @@ -125,6 +125,8 @@ func (p *Plugin) ExecuteCommand(_ *plugin.Context, args *model.CommandArgs) (*mo handler = p.runListCommand case "pop": handler = p.runPopCommand + case "remove": + handler = p.runRemoveCommand case "send": handler = p.runSendCommand case "settings": @@ -328,6 +330,53 @@ func (p *Plugin) runPopCommand(_ []string, extra *model.CommandArgs) (bool, erro return false, nil } +func (p *Plugin) runRemoveCommand(args []string, extra *model.CommandArgs) (bool, error) { + if len(args) < 2 || args[0] != "--todo" { + p.postCommandResponse(extra, "Invalid command provided") + return false, nil + } + + todoID := args[1] + if todoID == "" { + p.postCommandResponse(extra, "Empty todoID provided") + return false, nil + } + + issue, foreignID, _, _, err := p.listManager.RemoveIssue(extra.UserId, todoID) + if err != nil { + return false, err + } + + userName := p.listManager.GetUserName(extra.UserId) + + if foreignID != "" { + p.sendRefreshEvent(foreignID, []string{OutListKey}) + + message := fmt.Sprintf("@%s removed a Todo you sent: %s", userName, issue.Message) + p.PostBotDM(foreignID, message) + } + + p.sendRefreshEvent(extra.UserId, []string{MyListKey}) + + responseMessage := fmt.Sprintf("Removed given Todo (%s).", issue.Message) + + replyMessage := fmt.Sprintf("@%s removed a todo attached to this thread", userName) + p.postReplyIfNeeded(issue.PostID, replyMessage, issue.Message) + + issues, err := p.listManager.GetIssueList(extra.UserId, MyListKey) + if err != nil { + p.API.LogError(err.Error()) + p.postCommandResponse(extra, responseMessage) + return false, nil + } + + responseMessage += listHeaderMessage + responseMessage += issuesListToString(issues) + p.postCommandResponse(extra, responseMessage) + + return false, nil +} + func (p *Plugin) runSettingsCommand(args []string, extra *model.CommandArgs) (bool, error) { const ( on = "on" @@ -419,7 +468,7 @@ func (p *Plugin) runSettingsCommand(args []string, extra *model.CommandArgs) (bo } func getAutocompleteData() *model.AutocompleteData { - todo := model.NewAutocompleteData("todo", "[command]", "Available commands: list, add, pop, send, settings, help") + todo := model.NewAutocompleteData("todo", "[command]", "Available commands: list, add, pop, remove, send, settings, help") add := model.NewAutocompleteData("add", "[message]", "Adds a Todo") add.AddTextArgument("E.g. be awesome", "[message]", "") @@ -441,6 +490,10 @@ func getAutocompleteData() *model.AutocompleteData { pop := model.NewAutocompleteData("pop", "", "Removes the Todo issue at the top of the list") todo.AddCommand(pop) + remove := model.NewAutocompleteData("remove", "--todo id", "Removes the given Todo") + remove.AddNamedDynamicListArgument("todo", "--todo todoID", getAutocompletePath(AutocompletePathRemoveTodoSuggestions), true) + todo.AddCommand(remove) + send := model.NewAutocompleteData("send", "[user] [todo]", "Sends a Todo to a specified user") send.AddTextArgument("Whom to send", "[@awesomePerson]", "") send.AddTextArgument("Todo message", "[message]", "") @@ -467,3 +520,7 @@ func getAutocompleteData() *model.AutocompleteData { todo.AddCommand(help) return todo } + +func getAutocompletePath(path string) string { + return "plugins/" + manifest.Id + "/autocomplete" + path +} diff --git a/server/constants.go b/server/constants.go new file mode 100644 index 00000000..a87564ba --- /dev/null +++ b/server/constants.go @@ -0,0 +1,6 @@ +package main + +const ( + AutocompletePath = "/autocomplete" + AutocompletePathRemoveTodoSuggestions = "/getRemoveTodoSuggestions" +) diff --git a/server/plugin.go b/server/plugin.go index e9651fa5..398c1fe0 100644 --- a/server/plugin.go +++ b/server/plugin.go @@ -130,6 +130,7 @@ func (p *Plugin) initializeAPI() { p.router.HandleFunc("/config", p.checkAuth(p.handleConfig)).Methods(http.MethodGet) p.router.HandleFunc("/edit", p.checkAuth(p.handleEdit)).Methods(http.MethodPut) p.router.HandleFunc("/change_assignment", p.checkAuth(p.handleChangeAssignment)).Methods(http.MethodPost) + p.router.HandleFunc(AutocompletePath + AutocompletePathRemoveTodoSuggestions, p.checkAuth(p.getRemoveTodoSuggestions)).Methods(http.MethodPost) // 404 handler p.router.Handle("{anything:.*}", http.NotFoundHandler()) @@ -335,8 +336,8 @@ func (p *Plugin) handleList(w http.ResponseWriter, r *http.Request) { issuesJSON, err := json.Marshal(issues) if err != nil { - p.API.LogError("Unable marhsal issues list to json err=" + err.Error()) - p.handleErrorWithCode(w, http.StatusInternalServerError, "Unable marhsal issues list to json", err) + p.API.LogError("Unable marshal issues list to json err=" + err.Error()) + p.handleErrorWithCode(w, http.StatusInternalServerError, "Unable marshal issues list to json", err) return } @@ -654,3 +655,40 @@ func (p *Plugin) handleErrorWithCode(w http.ResponseWriter, code int, errTitle s }) _, _ = w.Write(b) } + +func (p *Plugin) getRemoveTodoSuggestions(w http.ResponseWriter, r *http.Request) { + userID := r.Header.Get("Mattermost-User-ID") + if userID == "" { + http.Error(w, "Not authorized", http.StatusUnauthorized) + return + } + listID := MyListKey + issues, err := p.listManager.GetIssueList(userID, listID) + if err != nil { + p.API.LogError("Unable to get issues for user err=" + err.Error()) + p.handleErrorWithCode(w, http.StatusInternalServerError, "Unable to get issues for user", err) + return + } + + out := []model.AutocompleteListItem{} + for _, issue := range issues { + s := model.AutocompleteListItem{ + Item: issue.ID, + Hint: issue.Message, + HelpText: issue.Description, + } + out = append(out, s) + } + + outJSON, err := json.Marshal(out) + if err != nil { + p.API.LogError("Unable marshal issues list to json err=" + err.Error()) + p.handleErrorWithCode(w, http.StatusInternalServerError, "Unable marshal issues list to json", err) + return + } + + _, err = w.Write(outJSON) + if err != nil { + p.API.LogError("Unable to write json response err=" + err.Error()) + } +}