MM-30212 Support dynamic autocomplete for built-in slash commands (#16196)

Support added for dynamic auto-completion lists for built-in slash commands.

* a moniker within the fetch url determines whether the request should be sent via HTTP(S) or routed internally to a built-in command. The moniker is of the form builtin: followed by the name of the built-in command to use. e.g. builtin:share would be become a call to the share command to fetch auto-completion items.

* command providers implement the optional DynamicListProvider interface to indicate they can provide dynamic auto-completion.
Этот коммит содержится в:
Doug Lauder
2020-11-13 21:10:07 -05:00
коммит произвёл GitHub
родитель 46a409aef6
Коммит 277f886b3f
2 изменённых файлов: 102 добавлений и 0 удалений

Просмотреть файл

@@ -4,6 +4,8 @@
package app
import (
"errors"
"fmt"
"net/url"
"sort"
"strings"
@@ -12,6 +14,11 @@ import (
"github.com/mattermost/mattermost-server/v5/model"
)
// AutocompleteDynamicArgProvider dynamically provides auto-completion args for built-in commands.
type AutocompleteDynamicArgProvider interface {
GetAutoCompleteListItems(a *App, commandArgs *model.CommandArgs, arg *model.AutocompleteArg, parsed, toBeParsed string) ([]model.AutocompleteListItem, error)
}
// GetSuggestions returns suggestions for user input.
func (a *App) GetSuggestions(commandArgs *model.CommandArgs, commands []*model.Command, roleID string) []model.AutocompleteSuggestion {
sort.Slice(commands, func(i, j int) bool {
@@ -233,6 +240,15 @@ func parseStaticListArgument(arg *model.AutocompleteArg, parsed, toBeParsed stri
func (a *App) getDynamicListArgument(commandArgs *model.CommandArgs, arg *model.AutocompleteArg, parsed, toBeParsed string) (found bool, alreadyParsed string, yetToBeParsed string, suggestions []model.AutocompleteSuggestion) {
dynamicArg := arg.Data.(*model.AutocompleteDynamicListArg)
if strings.HasPrefix(dynamicArg.FetchURL, "builtin:") {
listItems, err := a.getBuiltinDynamicListArgument(commandArgs, arg, parsed, toBeParsed)
if err != nil {
a.Log().Error("Can't fetch dynamic list arguments for", mlog.String("url", dynamicArg.FetchURL), mlog.Err(err))
return false, parsed, toBeParsed, []model.AutocompleteSuggestion{}
}
return parseListItems(listItems, parsed, toBeParsed)
}
params := url.Values{}
params.Add("user_input", parsed+toBeParsed)
params.Add("parsed", parsed)
@@ -286,3 +302,24 @@ func parseListItems(items []model.AutocompleteListItem, parsed, toBeParsed strin
}
return true, parsed + toBeParsed, "", suggestions
}
func (a *App) getBuiltinDynamicListArgument(commandArgs *model.CommandArgs, arg *model.AutocompleteArg, parsed, toBeParsed string) ([]model.AutocompleteListItem, error) {
dynamicArg := arg.Data.(*model.AutocompleteDynamicListArg)
arr := strings.Split(dynamicArg.FetchURL, ":")
if len(arr) < 2 {
return nil, errors.New("Dynamic list URL missing built-in command name")
}
cmdName := arr[1]
provider := GetCommandProvider(cmdName)
if provider == nil {
return nil, fmt.Errorf("No command provider for %s", cmdName)
}
dp, ok := provider.(AutocompleteDynamicArgProvider)
if !ok {
return nil, fmt.Errorf("Auto-completion not available for built-in command %s", cmdName)
}
return dp.GetAutoCompleteListItems(a, commandArgs, arg, parsed, toBeParsed)
}