Revert "PLT-2183 Slash command auto-complete"
Этот коммит содержится в:
@@ -44,7 +44,7 @@ func InitCommand(r *mux.Router) {
|
||||
sr := r.PathPrefix("/commands").Subrouter()
|
||||
|
||||
sr.Handle("/execute", ApiUserRequired(executeCommand)).Methods("POST")
|
||||
sr.Handle("/list", ApiUserRequired(listCommands)).Methods("POST")
|
||||
sr.Handle("/list", ApiUserRequired(listCommands)).Methods("GET")
|
||||
|
||||
sr.Handle("/create", ApiUserRequired(createCommand)).Methods("POST")
|
||||
sr.Handle("/list_team_commands", ApiUserRequired(listTeamCommands)).Methods("GET")
|
||||
@@ -76,9 +76,7 @@ func listCommands(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
} else {
|
||||
teamCmds := result.Data.([]*model.Command)
|
||||
for _, cmd := range teamCmds {
|
||||
if cmd.ExternalManagement {
|
||||
commands = append(commands, autocompleteCommands(c, cmd, r)...)
|
||||
} else if cmd.AutoComplete && !seen[cmd.Id] {
|
||||
if cmd.AutoComplete && !seen[cmd.Id] {
|
||||
cmd.Sanitize()
|
||||
seen[cmd.Trigger] = true
|
||||
commands = append(commands, cmd)
|
||||
@@ -90,92 +88,6 @@ func listCommands(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
w.Write([]byte(model.CommandListToJson(commands)))
|
||||
}
|
||||
|
||||
func autocompleteCommands(c *Context, cmd *model.Command, r *http.Request) []*model.Command {
|
||||
props := model.MapFromJson(r.Body)
|
||||
command := strings.TrimSpace(props["command"])
|
||||
channelId := strings.TrimSpace(props["channelId"])
|
||||
parts := strings.Split(command, " ")
|
||||
trigger := parts[0][1:]
|
||||
message := strings.Join(parts[1:], " ")
|
||||
|
||||
chanChan := Srv.Store.Channel().Get(channelId)
|
||||
teamChan := Srv.Store.Team().Get(c.Session.TeamId)
|
||||
userChan := Srv.Store.User().Get(c.Session.UserId)
|
||||
|
||||
var team *model.Team
|
||||
if tr := <-teamChan; tr.Err != nil {
|
||||
c.Err = tr.Err
|
||||
return make([]*model.Command, 0, 32)
|
||||
} else {
|
||||
team = tr.Data.(*model.Team)
|
||||
}
|
||||
|
||||
var user *model.User
|
||||
if ur := <-userChan; ur.Err != nil {
|
||||
c.Err = ur.Err
|
||||
return make([]*model.Command, 0, 32)
|
||||
} else {
|
||||
user = ur.Data.(*model.User)
|
||||
}
|
||||
|
||||
var channel *model.Channel
|
||||
if cr := <-chanChan; cr.Err != nil {
|
||||
c.Err = cr.Err
|
||||
return make([]*model.Command, 0, 32)
|
||||
} else {
|
||||
channel = cr.Data.(*model.Channel)
|
||||
}
|
||||
|
||||
l4g.Debug(fmt.Sprintf(utils.T("api.command.execute_command.debug"), trigger, c.Session.UserId))
|
||||
p := url.Values{}
|
||||
p.Set("token", cmd.Token)
|
||||
|
||||
p.Set("team_id", cmd.TeamId)
|
||||
p.Set("team_domain", team.Name)
|
||||
|
||||
p.Set("channel_id", channelId)
|
||||
p.Set("channel_name", channel.Name)
|
||||
|
||||
p.Set("user_id", c.Session.UserId)
|
||||
p.Set("user_name", user.Username)
|
||||
|
||||
p.Set("command", "/"+trigger)
|
||||
p.Set("text", message)
|
||||
p.Set("response_url", "not supported yet")
|
||||
p.Set("suggest", "true")
|
||||
|
||||
method := "POST"
|
||||
if cmd.Method == model.COMMAND_METHOD_GET {
|
||||
method = "GET"
|
||||
}
|
||||
|
||||
tr := &http.Transport{
|
||||
TLSClientConfig: &tls.Config{InsecureSkipVerify: *utils.Cfg.ServiceSettings.EnableInsecureOutgoingConnections},
|
||||
}
|
||||
client := &http.Client{Transport: tr}
|
||||
|
||||
req, _ := http.NewRequest(method, cmd.URL, strings.NewReader(p.Encode()))
|
||||
req.Header.Set("Accept", "application/json")
|
||||
if cmd.Method == model.COMMAND_METHOD_POST {
|
||||
req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
|
||||
}
|
||||
|
||||
if resp, err := client.Do(req); err != nil {
|
||||
c.Err = model.NewLocAppError("command", "api.command.execute_command.failed.app_error", map[string]interface{}{"Trigger": trigger}, err.Error())
|
||||
} else {
|
||||
if resp.StatusCode == http.StatusOK {
|
||||
response := model.CommandListFromJson(resp.Body)
|
||||
|
||||
return response
|
||||
|
||||
} else {
|
||||
body, _ := ioutil.ReadAll(resp.Body)
|
||||
c.Err = model.NewLocAppError("command", "api.command.execute_command.failed_resp.app_error", map[string]interface{}{"Trigger": trigger, "Status": resp.Status}, string(body))
|
||||
}
|
||||
}
|
||||
return make([]*model.Command, 0, 32)
|
||||
}
|
||||
|
||||
func executeCommand(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
props := model.MapFromJson(r.Body)
|
||||
command := strings.TrimSpace(props["command"])
|
||||
@@ -247,7 +159,7 @@ func executeCommand(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
teamCmds := result.Data.([]*model.Command)
|
||||
for _, cmd := range teamCmds {
|
||||
if trigger == cmd.Trigger || cmd.ExternalManagement {
|
||||
if trigger == cmd.Trigger {
|
||||
l4g.Debug(fmt.Sprintf(utils.T("api.command.execute_command.debug"), trigger, c.Session.UserId))
|
||||
|
||||
p := url.Values{}
|
||||
|
||||
@@ -24,10 +24,7 @@ func TestListCommands(t *testing.T) {
|
||||
|
||||
Client.LoginByEmail(team.Name, user1.Email, "pwd")
|
||||
|
||||
channel1 := &model.Channel{DisplayName: "AA", Name: "aa" + model.NewId() + "a", Type: model.CHANNEL_OPEN, TeamId: team.Id}
|
||||
channel1 = Client.Must(Client.CreateChannel(channel1)).Data.(*model.Channel)
|
||||
|
||||
if results, err := Client.ListCommands(channel1.Id, "/test"); err != nil {
|
||||
if results, err := Client.ListCommands(); err != nil {
|
||||
t.Fatal(err)
|
||||
} else {
|
||||
commands := results.Data.([]*model.Command)
|
||||
|
||||
@@ -363,11 +363,8 @@ func (c *Client) Command(channelId string, command string, suggest bool) (*Resul
|
||||
}
|
||||
}
|
||||
|
||||
func (c *Client) ListCommands(channelId string, command string) (*Result, *AppError) {
|
||||
m := make(map[string]string)
|
||||
m["command"] = command
|
||||
m["channelId"] = channelId
|
||||
if r, err := c.DoApiPost("/commands/list", MapToJson(m)); err != nil {
|
||||
func (c *Client) ListCommands() (*Result, *AppError) {
|
||||
if r, err := c.DoApiGet("/commands/list", "", ""); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
return &Result{r.Header.Get(HEADER_REQUEST_ID),
|
||||
|
||||
@@ -14,23 +14,22 @@ const (
|
||||
)
|
||||
|
||||
type Command struct {
|
||||
Id string `json:"id"`
|
||||
Token string `json:"token"`
|
||||
CreateAt int64 `json:"create_at"`
|
||||
UpdateAt int64 `json:"update_at"`
|
||||
DeleteAt int64 `json:"delete_at"`
|
||||
CreatorId string `json:"creator_id"`
|
||||
TeamId string `json:"team_id"`
|
||||
ExternalManagement bool `json:"external_management"`
|
||||
Trigger string `json:"trigger"`
|
||||
Method string `json:"method"`
|
||||
Username string `json:"username"`
|
||||
IconURL string `json:"icon_url"`
|
||||
AutoComplete bool `json:"auto_complete"`
|
||||
AutoCompleteDesc string `json:"auto_complete_desc"`
|
||||
AutoCompleteHint string `json:"auto_complete_hint"`
|
||||
DisplayName string `json:"display_name"`
|
||||
URL string `json:"url"`
|
||||
Id string `json:"id"`
|
||||
Token string `json:"token"`
|
||||
CreateAt int64 `json:"create_at"`
|
||||
UpdateAt int64 `json:"update_at"`
|
||||
DeleteAt int64 `json:"delete_at"`
|
||||
CreatorId string `json:"creator_id"`
|
||||
TeamId string `json:"team_id"`
|
||||
Trigger string `json:"trigger"`
|
||||
Method string `json:"method"`
|
||||
Username string `json:"username"`
|
||||
IconURL string `json:"icon_url"`
|
||||
AutoComplete bool `json:"auto_complete"`
|
||||
AutoCompleteDesc string `json:"auto_complete_desc"`
|
||||
AutoCompleteHint string `json:"auto_complete_hint"`
|
||||
DisplayName string `json:"display_name"`
|
||||
URL string `json:"url"`
|
||||
}
|
||||
|
||||
func (o *Command) ToJson() string {
|
||||
|
||||
@@ -34,7 +34,6 @@ func NewSqlCommandStore(sqlStore *SqlStore) CommandStore {
|
||||
}
|
||||
|
||||
func (s SqlCommandStore) UpgradeSchemaIfNeeded() {
|
||||
s.CreateColumnIfNotExists("Commands", "ExternalManagement", "tinyint(1)", "boolean", "0")
|
||||
}
|
||||
|
||||
func (s SqlCommandStore) CreateIndexesIfNotExists() {
|
||||
|
||||
@@ -37,9 +37,9 @@ CommandSuggestion.propTypes = {
|
||||
};
|
||||
|
||||
export default class CommandProvider {
|
||||
handlePretextChanged(suggestionId, pretext, channelId) {
|
||||
handlePretextChanged(suggestionId, pretext) {
|
||||
if (pretext.startsWith('/')) {
|
||||
AsyncClient.getSuggestedCommands(pretext, channelId, suggestionId, CommandSuggestion);
|
||||
AsyncClient.getSuggestedCommands(pretext, suggestionId, CommandSuggestion);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -111,7 +111,7 @@ export default class SuggestionBox extends React.Component {
|
||||
|
||||
handlePretextChanged(pretext) {
|
||||
for (const provider of this.props.providers) {
|
||||
provider.handlePretextChanged(this.suggestionId, pretext, this.props.channelId);
|
||||
provider.handlePretextChanged(this.suggestionId, pretext);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -160,7 +160,6 @@ SuggestionBox.propTypes = {
|
||||
value: React.PropTypes.string.isRequired,
|
||||
onUserInput: React.PropTypes.func,
|
||||
providers: React.PropTypes.arrayOf(React.PropTypes.object),
|
||||
channelId: React.PropTypes.string,
|
||||
|
||||
// explicitly name any input event handlers we override and need to manually call
|
||||
onChange: React.PropTypes.func,
|
||||
|
||||
@@ -224,7 +224,6 @@ export default class Textbox extends React.Component {
|
||||
style={{visibility: this.state.preview ? 'hidden' : 'visible'}}
|
||||
listComponent={SuggestionList}
|
||||
providers={this.suggestionProviders}
|
||||
channelId={this.props.channelId}
|
||||
/>
|
||||
<div
|
||||
ref='preview'
|
||||
|
||||
@@ -4,13 +4,9 @@
|
||||
import LoadingScreen from '../loading_screen.jsx';
|
||||
|
||||
import * as Client from 'utils/client.jsx';
|
||||
import * as Utils from 'utils/utils.jsx';
|
||||
import Constants from 'utils/constants.jsx';
|
||||
|
||||
import {intlShape, injectIntl, defineMessages, FormattedMessage, FormattedHTMLMessage} from 'react-intl';
|
||||
|
||||
const PreReleaseFeatures = Constants.PRE_RELEASE_FEATURES;
|
||||
|
||||
const holders = defineMessages({
|
||||
requestTypePost: {
|
||||
id: 'user.settings.cmds.request_type_post',
|
||||
@@ -63,7 +59,6 @@ export default class ManageCommandCmds extends React.Component {
|
||||
this.getCmds = this.getCmds.bind(this);
|
||||
this.addNewCmd = this.addNewCmd.bind(this);
|
||||
this.emptyCmd = this.emptyCmd.bind(this);
|
||||
this.updateExternalManagement = this.updateExternalManagement.bind(this);
|
||||
this.updateTrigger = this.updateTrigger.bind(this);
|
||||
this.updateURL = this.updateURL.bind(this);
|
||||
this.updateMethod = this.updateMethod.bind(this);
|
||||
@@ -104,7 +99,7 @@ export default class ManageCommandCmds extends React.Component {
|
||||
addNewCmd(e) {
|
||||
e.preventDefault();
|
||||
|
||||
if (this.state.cmd.url === '' || (this.state.cmd.trigger === '' && !this.state.external_management)) {
|
||||
if (this.state.cmd.trigger === '' || this.state.cmd.url === '') {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -194,12 +189,6 @@ export default class ManageCommandCmds extends React.Component {
|
||||
);
|
||||
}
|
||||
|
||||
updateExternalManagement(e) {
|
||||
var cmd = this.state.cmd;
|
||||
cmd.external_management = e.target.checked;
|
||||
this.setState(cmd);
|
||||
}
|
||||
|
||||
updateTrigger(e) {
|
||||
var cmd = this.state.cmd;
|
||||
cmd.trigger = e.target.value;
|
||||
@@ -281,26 +270,11 @@ export default class ManageCommandCmds extends React.Component {
|
||||
);
|
||||
}
|
||||
|
||||
let slashCommandAutocompleteDiv;
|
||||
if (Utils.isFeatureEnabled(PreReleaseFeatures.SLASHCMD_AUTOCMP)) {
|
||||
slashCommandAutocompleteDiv = (
|
||||
<div className='padding-top x2'>
|
||||
<strong>
|
||||
<FormattedMessage
|
||||
id='user.settings.cmds.external_management'
|
||||
defaultMessage='External management: '
|
||||
/>
|
||||
</strong><span className='word-break--all'>{cmd.external_management ? this.props.intl.formatMessage(holders.autocompleteYes) : this.props.intl.formatMessage(holders.autocompleteNo)}</span>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
cmds.push(
|
||||
<div
|
||||
key={cmd.id}
|
||||
className='webhook__item webcmd__item'
|
||||
>
|
||||
{slashCommandAutocompleteDiv}
|
||||
{triggerDiv}
|
||||
<div className='padding-top x2 webcmd__url'>
|
||||
<strong>
|
||||
@@ -442,170 +416,7 @@ export default class ManageCommandCmds extends React.Component {
|
||||
</div>
|
||||
);
|
||||
|
||||
const disableButton = this.state.cmd.url === '' || (this.state.cmd.trigger === '' && !this.state.external_management);
|
||||
|
||||
let triggerInput;
|
||||
if (!this.state.cmd.external_management) {
|
||||
triggerInput = (
|
||||
<div className='padding-top x2'>
|
||||
<label className='control-label'>
|
||||
<FormattedMessage
|
||||
id='user.settings.cmds.trigger'
|
||||
defaultMessage='Command Trigger Word: '
|
||||
/>
|
||||
</label>
|
||||
<div className='padding-top'>
|
||||
<input
|
||||
ref='trigger'
|
||||
className='form-control'
|
||||
value={this.state.cmd.trigger}
|
||||
onChange={this.updateTrigger}
|
||||
placeholder={this.props.intl.formatMessage(holders.addTriggerPlaceholder)}
|
||||
/>
|
||||
</div>
|
||||
<div className='padding-top'>
|
||||
<FormattedMessage
|
||||
id='user.settings.cmds.trigger_desc'
|
||||
defaultMessage='Examples: /patient, /client, /employee Reserved: /echo, /join, /logout, /me, /shrug'
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
let slashCommandAutocompleteCheckbox;
|
||||
if (Utils.isFeatureEnabled(PreReleaseFeatures.SLASHCMD_AUTOCMP)) {
|
||||
slashCommandAutocompleteCheckbox = (
|
||||
<div className='padding-top x2'>
|
||||
<label className='control-label'>
|
||||
<FormattedMessage
|
||||
id='user.settings.cmds.external_management'
|
||||
defaultMessage='External management: '
|
||||
/>
|
||||
</label>
|
||||
<div className='padding-top'>
|
||||
<div className='checkbox'>
|
||||
<label>
|
||||
<input
|
||||
type='checkbox'
|
||||
checked={this.state.cmd.external_management}
|
||||
onChange={this.updateExternalManagement}
|
||||
/>
|
||||
<FormattedMessage
|
||||
id='user.settings.cmds.slashCmd_autocmp'
|
||||
defaultMessage='Enable external application to offer autocomplete'
|
||||
/>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
);
|
||||
}
|
||||
|
||||
let autoCompleteSettings;
|
||||
if (!this.state.cmd.external_management) {
|
||||
autoCompleteSettings = (
|
||||
<div>
|
||||
<div className='padding-top x2'>
|
||||
<label className='control-label'>
|
||||
<FormattedMessage
|
||||
id='user.settings.cmds.auto_complete'
|
||||
defaultMessage='Autocomplete: '
|
||||
/>
|
||||
</label>
|
||||
<div className='padding-top'>
|
||||
<div className='checkbox'>
|
||||
<label>
|
||||
<input
|
||||
type='checkbox'
|
||||
checked={this.state.cmd.auto_complete}
|
||||
onChange={this.updateAutoComplete}
|
||||
/>
|
||||
<FormattedMessage
|
||||
id='user.settings.cmds.auto_complete_help'
|
||||
defaultMessage=' Show this command in the autocomplete list.'
|
||||
/>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className='padding-top x2'>
|
||||
<label className='control-label'>
|
||||
<FormattedMessage
|
||||
id='user.settings.cmds.auto_complete_hint'
|
||||
defaultMessage='Autocomplete Hint: '
|
||||
/>
|
||||
</label>
|
||||
<div className='padding-top'>
|
||||
<input
|
||||
ref='autoCompleteHint'
|
||||
className='form-control'
|
||||
value={this.state.cmd.auto_complete_hint}
|
||||
onChange={this.updateAutoCompleteHint}
|
||||
placeholder={this.props.intl.formatMessage(holders.addAutoCompleteHintPlaceholder)}
|
||||
/>
|
||||
</div>
|
||||
<div className='padding-top'>
|
||||
<FormattedMessage
|
||||
id='user.settings.cmds.auto_complete_hint_desc'
|
||||
defaultMessage='Optional hint in the autocomplete list about parameters needed for command.'
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className='padding-top x2'>
|
||||
<label className='control-label'>
|
||||
<FormattedMessage
|
||||
id='user.settings.cmds.auto_complete_desc'
|
||||
defaultMessage='Autocomplete Description: '
|
||||
/>
|
||||
</label>
|
||||
<div className='padding-top'>
|
||||
<input
|
||||
ref='autoCompleteDesc'
|
||||
className='form-control'
|
||||
value={this.state.cmd.auto_complete_desc}
|
||||
onChange={this.updateAutoCompleteDesc}
|
||||
placeholder={this.props.intl.formatMessage(holders.addAutoCompleteDescPlaceholder)}
|
||||
/>
|
||||
</div>
|
||||
<div className='padding-top'>
|
||||
<FormattedMessage
|
||||
id='user.settings.cmds.auto_complete_desc_desc'
|
||||
defaultMessage='Optional short description of slash command for the autocomplete list.'
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className='padding-top x2'>
|
||||
<label className='control-label'>
|
||||
<FormattedMessage
|
||||
id='user.settings.cmds.display_name'
|
||||
defaultMessage='Descriptive Label: '
|
||||
/>
|
||||
</label>
|
||||
<div className='padding-top'>
|
||||
<input
|
||||
ref='displayName'
|
||||
className='form-control'
|
||||
value={this.state.cmd.display_name}
|
||||
onChange={this.updateDisplayName}
|
||||
placeholder={this.props.intl.formatMessage(holders.addDisplayNamePlaceholder)}
|
||||
/>
|
||||
</div>
|
||||
<div className='padding-top'>
|
||||
<FormattedMessage
|
||||
id='user.settings.cmds.cmd_display_name'
|
||||
defaultMessage='Brief description of slash command to show in listings.'
|
||||
/>
|
||||
</div>
|
||||
{addError}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
const disableButton = this.state.cmd.trigger === '' || this.state.cmd.url === '';
|
||||
|
||||
return (
|
||||
<div key='addCommandCmd'>
|
||||
@@ -622,8 +433,29 @@ export default class ManageCommandCmds extends React.Component {
|
||||
<div className='padding-top divider-light'></div>
|
||||
<div className='padding-top'>
|
||||
|
||||
{slashCommandAutocompleteCheckbox}
|
||||
{triggerInput}
|
||||
<div className='padding-top x2'>
|
||||
<label className='control-label'>
|
||||
<FormattedMessage
|
||||
id='user.settings.cmds.trigger'
|
||||
defaultMessage='Command Trigger Word: '
|
||||
/>
|
||||
</label>
|
||||
<div className='padding-top'>
|
||||
<input
|
||||
ref='trigger'
|
||||
className='form-control'
|
||||
value={this.state.cmd.trigger}
|
||||
onChange={this.updateTrigger}
|
||||
placeholder={this.props.intl.formatMessage(holders.addTriggerPlaceholder)}
|
||||
/>
|
||||
</div>
|
||||
<div className='padding-top'>
|
||||
<FormattedMessage
|
||||
id='user.settings.cmds.trigger_desc'
|
||||
defaultMessage='Examples: /patient, /client, /employee Reserved: /echo, /join, /logout, /me, /shrug'
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className='padding-top x2'>
|
||||
<label className='control-label'>
|
||||
@@ -728,7 +560,102 @@ export default class ManageCommandCmds extends React.Component {
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{autoCompleteSettings}
|
||||
<div className='padding-top x2'>
|
||||
<label className='control-label'>
|
||||
<FormattedMessage
|
||||
id='user.settings.cmds.auto_complete'
|
||||
defaultMessage='Autocomplete: '
|
||||
/>
|
||||
</label>
|
||||
<div className='padding-top'>
|
||||
<div className='checkbox'>
|
||||
<label>
|
||||
<input
|
||||
type='checkbox'
|
||||
checked={this.state.cmd.auto_complete}
|
||||
onChange={this.updateAutoComplete}
|
||||
/>
|
||||
<FormattedMessage
|
||||
id='user.settings.cmds.auto_complete_help'
|
||||
defaultMessage=' Show this command in the autocomplete list.'
|
||||
/>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className='padding-top x2'>
|
||||
<label className='control-label'>
|
||||
<FormattedMessage
|
||||
id='user.settings.cmds.auto_complete_hint'
|
||||
defaultMessage='Autocomplete Hint: '
|
||||
/>
|
||||
</label>
|
||||
<div className='padding-top'>
|
||||
<input
|
||||
ref='autoCompleteHint'
|
||||
className='form-control'
|
||||
value={this.state.cmd.auto_complete_hint}
|
||||
onChange={this.updateAutoCompleteHint}
|
||||
placeholder={this.props.intl.formatMessage(holders.addAutoCompleteHintPlaceholder)}
|
||||
/>
|
||||
</div>
|
||||
<div className='padding-top'>
|
||||
<FormattedMessage
|
||||
id='user.settings.cmds.auto_complete_hint_desc'
|
||||
defaultMessage='Optional hint in the autocomplete list about parameters needed for command.'
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className='padding-top x2'>
|
||||
<label className='control-label'>
|
||||
<FormattedMessage
|
||||
id='user.settings.cmds.auto_complete_desc'
|
||||
defaultMessage='Autocomplete Description: '
|
||||
/>
|
||||
</label>
|
||||
<div className='padding-top'>
|
||||
<input
|
||||
ref='autoCompleteDesc'
|
||||
className='form-control'
|
||||
value={this.state.cmd.auto_complete_desc}
|
||||
onChange={this.updateAutoCompleteDesc}
|
||||
placeholder={this.props.intl.formatMessage(holders.addAutoCompleteDescPlaceholder)}
|
||||
/>
|
||||
</div>
|
||||
<div className='padding-top'>
|
||||
<FormattedMessage
|
||||
id='user.settings.cmds.auto_complete_desc_desc'
|
||||
defaultMessage='Optional short description of slash command for the autocomplete list.'
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className='padding-top x2'>
|
||||
<label className='control-label'>
|
||||
<FormattedMessage
|
||||
id='user.settings.cmds.display_name'
|
||||
defaultMessage='Descriptive Label: '
|
||||
/>
|
||||
</label>
|
||||
<div className='padding-top'>
|
||||
<input
|
||||
ref='displayName'
|
||||
className='form-control'
|
||||
value={this.state.cmd.display_name}
|
||||
onChange={this.updateDisplayName}
|
||||
placeholder={this.props.intl.formatMessage(holders.addDisplayNamePlaceholder)}
|
||||
/>
|
||||
</div>
|
||||
<div className='padding-top'>
|
||||
<FormattedMessage
|
||||
id='user.settings.cmds.cmd_display_name'
|
||||
defaultMessage='Brief description of slash command to show in listings.'
|
||||
/>
|
||||
</div>
|
||||
{addError}
|
||||
</div>
|
||||
|
||||
<div className='padding-top x2 padding-bottom'>
|
||||
<a
|
||||
|
||||
@@ -51,10 +51,6 @@ const holders = defineMessages({
|
||||
EMBED_TOGGLE: {
|
||||
id: 'user.settings.advance.embed_toggle',
|
||||
defaultMessage: 'Show toggle for all embed previews'
|
||||
},
|
||||
SLASHCMD_AUTOCMP: {
|
||||
id: 'user.settings.advance.slashCmd_autocmp',
|
||||
defaultMessage: 'Enable external application to offer slash command autocomplete'
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@@ -1130,7 +1130,6 @@
|
||||
"tutorial_tip.seen": "Seen this before? ",
|
||||
"upload_overlay.info": "Drop a file to upload it.",
|
||||
"user.settings.advance.embed_preview": "Show preview snippet of links below message",
|
||||
"user.settings.advance.slashCmd_autocmp": "Enable external application to offer slash command autocomplete",
|
||||
"user.settings.advance.embed_toggle": "Show toggle for all embed previews",
|
||||
"user.settings.advance.enabled": "enabled",
|
||||
"user.settings.advance.feature": " Feature ",
|
||||
@@ -1178,7 +1177,6 @@
|
||||
"user.settings.cmds.url_desc": "The callback URL to receive the HTTP POST or GET event request when the slash command is run.",
|
||||
"user.settings.cmds.username": "Response Username: ",
|
||||
"user.settings.cmds.username_desc": "Choose a username override for responses for this slash command. Usernames can consist of up to 22 characters consisting of lowercase letters, numbers and they symbols \"-\", \"_\", and \".\" .",
|
||||
"user.settings.cmds.slashCmd_autocmp": "Enable external application to offer autocomplete",
|
||||
"user.settings.custom_theme.awayIndicator": "Away Indicator",
|
||||
"user.settings.custom_theme.buttonBg": "Button BG",
|
||||
"user.settings.custom_theme.buttonColor": "Button Text",
|
||||
|
||||
@@ -781,12 +781,12 @@ export function savePreferences(preferences, success, error) {
|
||||
);
|
||||
}
|
||||
|
||||
export function getSuggestedCommands(command, channelId, suggestionId, component) {
|
||||
client.listCommands({command: command, channelId: channelId},
|
||||
export function getSuggestedCommands(command, suggestionId, component) {
|
||||
client.listCommands(
|
||||
(data) => {
|
||||
var matches = [];
|
||||
data.forEach((cmd) => {
|
||||
if (('/' + cmd.trigger).indexOf(command) === 0 || cmd.external_management) {
|
||||
if (('/' + cmd.trigger).indexOf(command) === 0) {
|
||||
let s = '/' + cmd.trigger;
|
||||
let hint = '';
|
||||
if (cmd.auto_complete_hint && cmd.auto_complete_hint.length !== 0) {
|
||||
|
||||
@@ -1031,13 +1031,12 @@ export function regenCommandToken(data, success, error) {
|
||||
});
|
||||
}
|
||||
|
||||
export function listCommands(data, success, error) {
|
||||
export function listCommands(success, error) {
|
||||
$.ajax({
|
||||
url: '/api/v1/commands/list',
|
||||
dataType: 'json',
|
||||
contentType: 'application/json',
|
||||
type: 'POST',
|
||||
data: JSON.stringify(data),
|
||||
type: 'GET',
|
||||
success,
|
||||
error: function onError(xhr, status, err) {
|
||||
var e = handleError('listCommands', xhr, status, err);
|
||||
|
||||
@@ -595,10 +595,6 @@ export default {
|
||||
EMBED_TOGGLE: {
|
||||
label: 'embed_toggle',
|
||||
description: 'Show toggle for all embed previews'
|
||||
},
|
||||
SLASHCMD_AUTOCMP: {
|
||||
label: 'slashCmd_autocmp',
|
||||
description: 'Enable external application to offer slash command autocomplete'
|
||||
}
|
||||
},
|
||||
OVERLAY_TIME_DELAY: 400,
|
||||
|
||||
Ссылка в новой задаче
Block a user