mirror of
https://github.com/mattermost/mattermost.git
synced 2025-02-25 18:55:24 -06:00
Fix add command in backstage (#24043)
This commit is contained in:
parent
150c6e7aef
commit
66c2837d2c
@ -471,6 +471,475 @@ exports[`components/integrations/AbstractCommand should match snapshot 1`] = `
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`components/integrations/AbstractCommand should match snapshot when header/footer/loading is a string 1`] = `
|
||||
<div
|
||||
className="backstage-content row"
|
||||
>
|
||||
<BackstageHeader>
|
||||
<Link
|
||||
to="/test/integrations/commands"
|
||||
>
|
||||
<MemoizedFormattedMessage
|
||||
defaultMessage="Slash Commands"
|
||||
id="installed_command.header"
|
||||
/>
|
||||
</Link>
|
||||
<span>
|
||||
Header as string
|
||||
</span>
|
||||
</BackstageHeader>
|
||||
<div
|
||||
className="backstage-form"
|
||||
>
|
||||
<form
|
||||
className="form-horizontal"
|
||||
onSubmit={[Function]}
|
||||
>
|
||||
<div
|
||||
className="form-group"
|
||||
>
|
||||
<label
|
||||
className="control-label col-sm-4"
|
||||
htmlFor="displayName"
|
||||
>
|
||||
<MemoizedFormattedMessage
|
||||
defaultMessage="Title"
|
||||
id="add_command.displayName"
|
||||
/>
|
||||
</label>
|
||||
<div
|
||||
className="col-md-5 col-sm-8"
|
||||
>
|
||||
<input
|
||||
className="form-control"
|
||||
id="displayName"
|
||||
maxLength={64}
|
||||
onChange={[Function]}
|
||||
type="text"
|
||||
value="display_name"
|
||||
/>
|
||||
<div
|
||||
className="form__help"
|
||||
>
|
||||
<MemoizedFormattedMessage
|
||||
defaultMessage="Specify a title, of up to 64 characters, for the slash command settings page."
|
||||
id="add_command.displayName.help"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
className="form-group"
|
||||
>
|
||||
<label
|
||||
className="control-label col-sm-4"
|
||||
htmlFor="description"
|
||||
>
|
||||
<MemoizedFormattedMessage
|
||||
defaultMessage="Description"
|
||||
id="add_command.description"
|
||||
/>
|
||||
</label>
|
||||
<div
|
||||
className="col-md-5 col-sm-8"
|
||||
>
|
||||
<input
|
||||
className="form-control"
|
||||
id="description"
|
||||
maxLength={128}
|
||||
onChange={[Function]}
|
||||
type="text"
|
||||
value="description"
|
||||
/>
|
||||
<div
|
||||
className="form__help"
|
||||
>
|
||||
<MemoizedFormattedMessage
|
||||
defaultMessage="Describe your slash command."
|
||||
id="add_command.description.help"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
className="form-group"
|
||||
>
|
||||
<label
|
||||
className="control-label col-sm-4"
|
||||
htmlFor="trigger"
|
||||
>
|
||||
<MemoizedFormattedMessage
|
||||
defaultMessage="Command Trigger Word"
|
||||
id="add_command.trigger"
|
||||
/>
|
||||
</label>
|
||||
<div
|
||||
className="col-md-5 col-sm-8"
|
||||
>
|
||||
<LocalizedInput
|
||||
className="form-control"
|
||||
id="trigger"
|
||||
maxLength={128}
|
||||
onChange={[Function]}
|
||||
placeholder={
|
||||
Object {
|
||||
"defaultMessage": "Command trigger e.g. \\"hello\\" not including the slash",
|
||||
"id": "add_command.trigger.placeholder",
|
||||
}
|
||||
}
|
||||
type="text"
|
||||
value="trigger"
|
||||
/>
|
||||
<div
|
||||
className="form__help"
|
||||
>
|
||||
<MemoizedFormattedMessage
|
||||
defaultMessage="Specify a trigger word that is not a built-in command, does not contain spaces, and does not begin with the slash character."
|
||||
id="add_command.trigger.help"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
className="form__help"
|
||||
>
|
||||
<MemoizedFormattedMessage
|
||||
defaultMessage="Examples: client, employee, patient, weather"
|
||||
id="add_command.trigger.helpExamples"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
className="form__help"
|
||||
>
|
||||
<MemoizedFormattedMessage
|
||||
defaultMessage="Reserved: {link}"
|
||||
id="add_command.trigger.helpReserved"
|
||||
values={
|
||||
Object {
|
||||
"link": <ExternalLink
|
||||
href="https://mattermost.com/pl/custom-slash-commands"
|
||||
location="abstract_command"
|
||||
>
|
||||
<Memo(MemoizedFormattedMessage)
|
||||
defaultMessage="See built-in slash commands"
|
||||
id="add_command.trigger.helpReservedLinkText"
|
||||
/>
|
||||
</ExternalLink>,
|
||||
}
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
className="form-group"
|
||||
>
|
||||
<label
|
||||
className="control-label col-sm-4"
|
||||
htmlFor="url"
|
||||
>
|
||||
<MemoizedFormattedMessage
|
||||
defaultMessage="Request URL"
|
||||
id="add_command.url"
|
||||
/>
|
||||
</label>
|
||||
<div
|
||||
className="col-md-5 col-sm-8"
|
||||
>
|
||||
<LocalizedInput
|
||||
className="form-control"
|
||||
id="url"
|
||||
maxLength={1024}
|
||||
onChange={[Function]}
|
||||
placeholder={
|
||||
Object {
|
||||
"defaultMessage": "Must start with http:// or https://",
|
||||
"id": "add_command.url.placeholder",
|
||||
}
|
||||
}
|
||||
type="text"
|
||||
value="https://google.com/command"
|
||||
/>
|
||||
<div
|
||||
className="form__help"
|
||||
>
|
||||
<MemoizedFormattedMessage
|
||||
defaultMessage="Specify the callback URL to receive the HTTP POST or GET event request when the slash command is run."
|
||||
id="add_command.url.help"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
className="form-group"
|
||||
>
|
||||
<label
|
||||
className="control-label col-sm-4"
|
||||
htmlFor="method"
|
||||
>
|
||||
<MemoizedFormattedMessage
|
||||
defaultMessage="Request Method"
|
||||
id="add_command.method"
|
||||
/>
|
||||
</label>
|
||||
<div
|
||||
className="col-md-5 col-sm-8"
|
||||
>
|
||||
<select
|
||||
className="form-control"
|
||||
id="method"
|
||||
onChange={[Function]}
|
||||
value="G"
|
||||
>
|
||||
<option
|
||||
value="P"
|
||||
>
|
||||
POST
|
||||
</option>
|
||||
<option
|
||||
value="G"
|
||||
>
|
||||
GET
|
||||
</option>
|
||||
</select>
|
||||
<div
|
||||
className="form__help"
|
||||
>
|
||||
<MemoizedFormattedMessage
|
||||
defaultMessage="Specify the type of request, either POST or GET, sent to the endpoint that Mattermost hits to reach your application."
|
||||
id="add_command.method.help"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
className="form-group"
|
||||
>
|
||||
<label
|
||||
className="control-label col-sm-4"
|
||||
htmlFor="username"
|
||||
>
|
||||
<MemoizedFormattedMessage
|
||||
defaultMessage="Response Username"
|
||||
id="add_command.username"
|
||||
/>
|
||||
</label>
|
||||
<div
|
||||
className="col-md-5 col-sm-8"
|
||||
>
|
||||
<LocalizedInput
|
||||
className="form-control"
|
||||
id="username"
|
||||
maxLength={64}
|
||||
onChange={[Function]}
|
||||
placeholder={
|
||||
Object {
|
||||
"defaultMessage": "Username",
|
||||
"id": "add_command.username.placeholder",
|
||||
}
|
||||
}
|
||||
type="text"
|
||||
value="username"
|
||||
/>
|
||||
<div
|
||||
className="form__help"
|
||||
>
|
||||
<MemoizedFormattedMessage
|
||||
defaultMessage="(Optional) Specify the name to use when posting responses for this slash command. Usernames can be up to 22 characters, and contain lowercase letters, numbers, and the symbols \\\\\\"-\\\\\\", \\\\\\"_\\\\\\", and \\\\\\".\\\\\\". If left blank, your Mattermost username is used."
|
||||
id="add_command.username.help"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
className="form-group"
|
||||
>
|
||||
<label
|
||||
className="control-label col-sm-4"
|
||||
htmlFor="iconUrl"
|
||||
>
|
||||
<MemoizedFormattedMessage
|
||||
defaultMessage="Response Icon"
|
||||
id="add_command.iconUrl"
|
||||
/>
|
||||
</label>
|
||||
<div
|
||||
className="col-md-5 col-sm-8"
|
||||
>
|
||||
<LocalizedInput
|
||||
className="form-control"
|
||||
id="iconUrl"
|
||||
maxLength={1024}
|
||||
onChange={[Function]}
|
||||
placeholder={
|
||||
Object {
|
||||
"defaultMessage": "https://www.example.com/myicon.png",
|
||||
"id": "add_command.iconUrl.placeholder",
|
||||
}
|
||||
}
|
||||
type="text"
|
||||
value="https://google.com/icon"
|
||||
/>
|
||||
<div
|
||||
className="form__help"
|
||||
>
|
||||
<MemoizedFormattedMessage
|
||||
defaultMessage="(Optional) Enter the URL of a .png or .jpg file to use as the icon when posting responses to this slash command. The file must be at least 128 pixels by 128 pixels. If left blank, your profile picture is used."
|
||||
id="add_command.iconUrl.help"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
className="form-group"
|
||||
>
|
||||
<label
|
||||
className="control-label col-sm-4"
|
||||
htmlFor="autocomplete"
|
||||
>
|
||||
<MemoizedFormattedMessage
|
||||
defaultMessage="Autocomplete"
|
||||
id="add_command.autocomplete"
|
||||
/>
|
||||
</label>
|
||||
<div
|
||||
className="col-md-5 col-sm-8 checkbox"
|
||||
>
|
||||
<input
|
||||
checked={true}
|
||||
id="autocomplete"
|
||||
onChange={[Function]}
|
||||
type="checkbox"
|
||||
/>
|
||||
<div
|
||||
className="form__help"
|
||||
>
|
||||
<MemoizedFormattedMessage
|
||||
defaultMessage="(Optional) Show your slash command on the autocomplete list when someone types \\"/\\" in the input box."
|
||||
id="add_command.autocomplete.help"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
className="form-group"
|
||||
>
|
||||
<label
|
||||
className="control-label col-sm-4"
|
||||
htmlFor="autocompleteHint"
|
||||
>
|
||||
<MemoizedFormattedMessage
|
||||
defaultMessage="Autocomplete Hint"
|
||||
id="add_command.autocompleteHint"
|
||||
/>
|
||||
</label>
|
||||
<div
|
||||
className="col-md-5 col-sm-8"
|
||||
>
|
||||
<LocalizedInput
|
||||
className="form-control"
|
||||
id="autocompleteHint"
|
||||
maxLength={1024}
|
||||
onChange={[Function]}
|
||||
placeholder={
|
||||
Object {
|
||||
"defaultMessage": "Example: [Patient Name]",
|
||||
"id": "add_command.autocompleteHint.placeholder",
|
||||
}
|
||||
}
|
||||
type="text"
|
||||
value="auto_complete_hint"
|
||||
/>
|
||||
<div
|
||||
className="form__help"
|
||||
>
|
||||
<MemoizedFormattedMessage
|
||||
defaultMessage="(Optional) Specify the arguments associated with your slash command. These are displayed as help on the autocomplete list."
|
||||
id="add_command.autocompleteHint.help"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
className="form-group"
|
||||
>
|
||||
<label
|
||||
className="control-label col-sm-4"
|
||||
htmlFor="autocompleteDescription"
|
||||
>
|
||||
<MemoizedFormattedMessage
|
||||
defaultMessage="Autocomplete Description"
|
||||
id="add_command.autocompleteDescription"
|
||||
/>
|
||||
</label>
|
||||
<div
|
||||
className="col-md-5 col-sm-8"
|
||||
>
|
||||
<LocalizedInput
|
||||
className="form-control"
|
||||
id="description"
|
||||
maxLength={128}
|
||||
onChange={[Function]}
|
||||
placeholder={
|
||||
Object {
|
||||
"defaultMessage": "Example: \\"Returns search results for patient records\\"",
|
||||
"id": "add_command.autocompleteDescription.placeholder",
|
||||
}
|
||||
}
|
||||
type="text"
|
||||
value="auto_complete_desc"
|
||||
/>
|
||||
<div
|
||||
className="form__help"
|
||||
>
|
||||
<MemoizedFormattedMessage
|
||||
defaultMessage="(Optional) Describe your slash command for the autocomplete list."
|
||||
id="add_command.autocompleteDescription.help"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
className="backstage-form__footer"
|
||||
>
|
||||
<FormError
|
||||
error={null}
|
||||
errors={
|
||||
Array [
|
||||
"",
|
||||
null,
|
||||
]
|
||||
}
|
||||
type="backstage"
|
||||
/>
|
||||
<Link
|
||||
className="btn btn-link btn-sm"
|
||||
to="/test/integrations/commands"
|
||||
>
|
||||
<MemoizedFormattedMessage
|
||||
defaultMessage="Cancel"
|
||||
id="add_command.cancel"
|
||||
/>
|
||||
</Link>
|
||||
<SpinnerButton
|
||||
className="btn btn-primary"
|
||||
id="saveCommand"
|
||||
onClick={[Function]}
|
||||
spinning={false}
|
||||
spinningText="Loading as string"
|
||||
type="submit"
|
||||
>
|
||||
<span>
|
||||
Footer as string
|
||||
</span>
|
||||
</SpinnerButton>
|
||||
<div>
|
||||
renderExtra
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`components/integrations/AbstractCommand should match snapshot, displays client error 1`] = `
|
||||
<div
|
||||
className="backstage-content row"
|
||||
|
@ -60,6 +60,18 @@ describe('components/integrations/AbstractCommand', () => {
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test('should match snapshot when header/footer/loading is a string', () => {
|
||||
const wrapper = shallow<AbstractCommand>(
|
||||
<AbstractCommand
|
||||
{...baseProps}
|
||||
header='Header as string'
|
||||
loading={'Loading as string'}
|
||||
footer={'Footer as string'}
|
||||
/>,
|
||||
);
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test('should match snapshot, displays client error', () => {
|
||||
const newSeverError = 'server error';
|
||||
const props = {...baseProps, serverError: newSeverError};
|
||||
|
@ -31,17 +31,17 @@ type Props = {
|
||||
/**
|
||||
* The header text to render, has id and defaultMessage
|
||||
*/
|
||||
header: MessageDescriptor;
|
||||
header: MessageDescriptor | string;
|
||||
|
||||
/**
|
||||
* The footer text to render, has id and defaultMessage
|
||||
*/
|
||||
footer: MessageDescriptor;
|
||||
footer: MessageDescriptor | string;
|
||||
|
||||
/**
|
||||
* The spinner loading text to render, has id and defaultMessage
|
||||
*/
|
||||
loading: MessageDescriptor;
|
||||
loading: MessageDescriptor | string;
|
||||
|
||||
/**
|
||||
* Any extra component/node to render
|
||||
@ -103,6 +103,32 @@ export default class AbstractCommand extends React.PureComponent<Props, State> {
|
||||
};
|
||||
};
|
||||
|
||||
getBackstageHeader = () => {
|
||||
if (typeof this.props.header === 'string') {
|
||||
return <span>{this.props.header}</span>;
|
||||
}
|
||||
|
||||
return (
|
||||
<FormattedMessage
|
||||
id={this.props.header.id}
|
||||
defaultMessage={this.props.header.defaultMessage}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
getBackstageFooter = () => {
|
||||
if (typeof this.props.footer === 'string') {
|
||||
return <span>{this.props.footer}</span>;
|
||||
}
|
||||
|
||||
return (
|
||||
<FormattedMessage
|
||||
id={this.props.footer.id}
|
||||
defaultMessage={this.props.footer.defaultMessage}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
handleSubmit = (e: React.FormEvent) => {
|
||||
e.preventDefault();
|
||||
|
||||
@ -362,10 +388,7 @@ export default class AbstractCommand extends React.PureComponent<Props, State> {
|
||||
defaultMessage='Slash Commands'
|
||||
/>
|
||||
</Link>
|
||||
<FormattedMessage
|
||||
id={this.props.header.id}
|
||||
defaultMessage={this.props.header.defaultMessage}
|
||||
/>
|
||||
{this.getBackstageHeader()}
|
||||
</BackstageHeader>
|
||||
<div className='backstage-form'>
|
||||
<form
|
||||
@ -640,14 +663,11 @@ export default class AbstractCommand extends React.PureComponent<Props, State> {
|
||||
className='btn btn-primary'
|
||||
type='submit'
|
||||
spinning={this.state.saving}
|
||||
spinningText={Utils.localizeMessage(this.props.loading?.id ?? '', this.props.loading?.defaultMessage as string)}
|
||||
spinningText={typeof this.props.loading === 'string' ? this.props.loading : Utils.localizeMessage(this.props.loading?.id ?? '', this.props.loading?.defaultMessage as string)}
|
||||
onClick={this.handleSubmit}
|
||||
id='saveCommand'
|
||||
>
|
||||
<FormattedMessage
|
||||
id={this.props.footer.id}
|
||||
defaultMessage={this.props.footer.defaultMessage}
|
||||
/>
|
||||
{this.getBackstageFooter()}
|
||||
</SpinnerButton>
|
||||
{this.props.renderExtra}
|
||||
</div>
|
||||
|
Loading…
Reference in New Issue
Block a user