MM-47095 Migrate AbstractIncomingWebhook to TypeScript (#22654)
Co-authored-by: Mattermost Build <build@mattermost.com>
Этот коммит содержится в:
@@ -1,7 +1,7 @@
|
|||||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||||
// See LICENSE.txt for license information.
|
// See LICENSE.txt for license information.
|
||||||
|
|
||||||
import React from 'react';
|
import React, {ChangeEventHandler} from 'react';
|
||||||
|
|
||||||
import {Channel} from '@mattermost/types/channels';
|
import {Channel} from '@mattermost/types/channels';
|
||||||
|
|
||||||
@@ -10,7 +10,7 @@ import * as Utils from 'utils/utils';
|
|||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
channels: Channel[];
|
channels: Channel[];
|
||||||
onChange?: () => void;
|
onChange?: ChangeEventHandler<HTMLSelectElement>;
|
||||||
value?: string;
|
value?: string;
|
||||||
selectOpen: boolean;
|
selectOpen: boolean;
|
||||||
selectPrivate: boolean;
|
selectPrivate: boolean;
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ exports[`components/integrations/AbstractIncomingWebhook should call action func
|
|||||||
<input
|
<input
|
||||||
className="form-control"
|
className="form-control"
|
||||||
id="displayName"
|
id="displayName"
|
||||||
maxLength="64"
|
maxLength={64}
|
||||||
onChange={[Function]}
|
onChange={[Function]}
|
||||||
type="text"
|
type="text"
|
||||||
value="testIncomingWebhook"
|
value="testIncomingWebhook"
|
||||||
@@ -76,7 +76,7 @@ exports[`components/integrations/AbstractIncomingWebhook should call action func
|
|||||||
<input
|
<input
|
||||||
className="form-control"
|
className="form-control"
|
||||||
id="description"
|
id="description"
|
||||||
maxLength="500"
|
maxLength={500}
|
||||||
onChange={[Function]}
|
onChange={[Function]}
|
||||||
type="text"
|
type="text"
|
||||||
value="testing"
|
value="testing"
|
||||||
@@ -107,8 +107,8 @@ exports[`components/integrations/AbstractIncomingWebhook should call action func
|
|||||||
className="col-md-5 col-sm-8"
|
className="col-md-5 col-sm-8"
|
||||||
>
|
>
|
||||||
<Connect(ChannelSelect)
|
<Connect(ChannelSelect)
|
||||||
id="channelId"
|
|
||||||
onChange={[Function]}
|
onChange={[Function]}
|
||||||
|
selectDm={false}
|
||||||
selectOpen={true}
|
selectOpen={true}
|
||||||
selectPrivate={true}
|
selectPrivate={true}
|
||||||
value="88cxd9wpzpbpfp8pad78xj75pr"
|
value="88cxd9wpzpbpfp8pad78xj75pr"
|
||||||
@@ -172,7 +172,7 @@ exports[`components/integrations/AbstractIncomingWebhook should call action func
|
|||||||
<input
|
<input
|
||||||
className="form-control"
|
className="form-control"
|
||||||
id="username"
|
id="username"
|
||||||
maxLength="22"
|
maxLength={22}
|
||||||
onChange={[Function]}
|
onChange={[Function]}
|
||||||
type="text"
|
type="text"
|
||||||
value=""
|
value=""
|
||||||
@@ -205,7 +205,7 @@ exports[`components/integrations/AbstractIncomingWebhook should call action func
|
|||||||
<input
|
<input
|
||||||
className="form-control"
|
className="form-control"
|
||||||
id="iconURL"
|
id="iconURL"
|
||||||
maxLength="1024"
|
maxLength={1024}
|
||||||
onChange={[Function]}
|
onChange={[Function]}
|
||||||
type="text"
|
type="text"
|
||||||
value=""
|
value=""
|
||||||
@@ -304,7 +304,7 @@ exports[`components/integrations/AbstractIncomingWebhook should match snapshot 1
|
|||||||
<input
|
<input
|
||||||
className="form-control"
|
className="form-control"
|
||||||
id="displayName"
|
id="displayName"
|
||||||
maxLength="64"
|
maxLength={64}
|
||||||
onChange={[Function]}
|
onChange={[Function]}
|
||||||
type="text"
|
type="text"
|
||||||
value="testIncomingWebhook"
|
value="testIncomingWebhook"
|
||||||
@@ -337,7 +337,7 @@ exports[`components/integrations/AbstractIncomingWebhook should match snapshot 1
|
|||||||
<input
|
<input
|
||||||
className="form-control"
|
className="form-control"
|
||||||
id="description"
|
id="description"
|
||||||
maxLength="500"
|
maxLength={500}
|
||||||
onChange={[Function]}
|
onChange={[Function]}
|
||||||
type="text"
|
type="text"
|
||||||
value="testing"
|
value="testing"
|
||||||
@@ -368,8 +368,8 @@ exports[`components/integrations/AbstractIncomingWebhook should match snapshot 1
|
|||||||
className="col-md-5 col-sm-8"
|
className="col-md-5 col-sm-8"
|
||||||
>
|
>
|
||||||
<Connect(ChannelSelect)
|
<Connect(ChannelSelect)
|
||||||
id="channelId"
|
|
||||||
onChange={[Function]}
|
onChange={[Function]}
|
||||||
|
selectDm={false}
|
||||||
selectOpen={true}
|
selectOpen={true}
|
||||||
selectPrivate={true}
|
selectPrivate={true}
|
||||||
value="88cxd9wpzpbpfp8pad78xj75pr"
|
value="88cxd9wpzpbpfp8pad78xj75pr"
|
||||||
@@ -433,7 +433,7 @@ exports[`components/integrations/AbstractIncomingWebhook should match snapshot 1
|
|||||||
<input
|
<input
|
||||||
className="form-control"
|
className="form-control"
|
||||||
id="username"
|
id="username"
|
||||||
maxLength="22"
|
maxLength={22}
|
||||||
onChange={[Function]}
|
onChange={[Function]}
|
||||||
type="text"
|
type="text"
|
||||||
value=""
|
value=""
|
||||||
@@ -466,7 +466,7 @@ exports[`components/integrations/AbstractIncomingWebhook should match snapshot 1
|
|||||||
<input
|
<input
|
||||||
className="form-control"
|
className="form-control"
|
||||||
id="iconURL"
|
id="iconURL"
|
||||||
maxLength="1024"
|
maxLength={1024}
|
||||||
onChange={[Function]}
|
onChange={[Function]}
|
||||||
type="text"
|
type="text"
|
||||||
value=""
|
value=""
|
||||||
@@ -565,7 +565,7 @@ exports[`components/integrations/AbstractIncomingWebhook should match snapshot,
|
|||||||
<input
|
<input
|
||||||
className="form-control"
|
className="form-control"
|
||||||
id="displayName"
|
id="displayName"
|
||||||
maxLength="64"
|
maxLength={64}
|
||||||
onChange={[Function]}
|
onChange={[Function]}
|
||||||
type="text"
|
type="text"
|
||||||
value=""
|
value=""
|
||||||
@@ -598,7 +598,7 @@ exports[`components/integrations/AbstractIncomingWebhook should match snapshot,
|
|||||||
<input
|
<input
|
||||||
className="form-control"
|
className="form-control"
|
||||||
id="description"
|
id="description"
|
||||||
maxLength="500"
|
maxLength={500}
|
||||||
onChange={[Function]}
|
onChange={[Function]}
|
||||||
type="text"
|
type="text"
|
||||||
value=""
|
value=""
|
||||||
@@ -629,8 +629,8 @@ exports[`components/integrations/AbstractIncomingWebhook should match snapshot,
|
|||||||
className="col-md-5 col-sm-8"
|
className="col-md-5 col-sm-8"
|
||||||
>
|
>
|
||||||
<Connect(ChannelSelect)
|
<Connect(ChannelSelect)
|
||||||
id="channelId"
|
|
||||||
onChange={[Function]}
|
onChange={[Function]}
|
||||||
|
selectDm={false}
|
||||||
selectOpen={true}
|
selectOpen={true}
|
||||||
selectPrivate={true}
|
selectPrivate={true}
|
||||||
value=""
|
value=""
|
||||||
@@ -694,7 +694,7 @@ exports[`components/integrations/AbstractIncomingWebhook should match snapshot,
|
|||||||
<input
|
<input
|
||||||
className="form-control"
|
className="form-control"
|
||||||
id="username"
|
id="username"
|
||||||
maxLength="22"
|
maxLength={22}
|
||||||
onChange={[Function]}
|
onChange={[Function]}
|
||||||
type="text"
|
type="text"
|
||||||
value=""
|
value=""
|
||||||
@@ -727,7 +727,7 @@ exports[`components/integrations/AbstractIncomingWebhook should match snapshot,
|
|||||||
<input
|
<input
|
||||||
className="form-control"
|
className="form-control"
|
||||||
id="iconURL"
|
id="iconURL"
|
||||||
maxLength="1024"
|
maxLength={1024}
|
||||||
onChange={[Function]}
|
onChange={[Function]}
|
||||||
type="text"
|
type="text"
|
||||||
value=""
|
value=""
|
||||||
@@ -829,7 +829,7 @@ exports[`components/integrations/AbstractIncomingWebhook should match snapshot,
|
|||||||
<input
|
<input
|
||||||
className="form-control"
|
className="form-control"
|
||||||
id="displayName"
|
id="displayName"
|
||||||
maxLength="64"
|
maxLength={64}
|
||||||
onChange={[Function]}
|
onChange={[Function]}
|
||||||
type="text"
|
type="text"
|
||||||
value="testIncomingWebhook"
|
value="testIncomingWebhook"
|
||||||
@@ -862,7 +862,7 @@ exports[`components/integrations/AbstractIncomingWebhook should match snapshot,
|
|||||||
<input
|
<input
|
||||||
className="form-control"
|
className="form-control"
|
||||||
id="description"
|
id="description"
|
||||||
maxLength="500"
|
maxLength={500}
|
||||||
onChange={[Function]}
|
onChange={[Function]}
|
||||||
type="text"
|
type="text"
|
||||||
value="testing"
|
value="testing"
|
||||||
@@ -893,8 +893,8 @@ exports[`components/integrations/AbstractIncomingWebhook should match snapshot,
|
|||||||
className="col-md-5 col-sm-8"
|
className="col-md-5 col-sm-8"
|
||||||
>
|
>
|
||||||
<Connect(ChannelSelect)
|
<Connect(ChannelSelect)
|
||||||
id="channelId"
|
|
||||||
onChange={[Function]}
|
onChange={[Function]}
|
||||||
|
selectDm={false}
|
||||||
selectOpen={true}
|
selectOpen={true}
|
||||||
selectPrivate={true}
|
selectPrivate={true}
|
||||||
value="88cxd9wpzpbpfp8pad78xj75pr"
|
value="88cxd9wpzpbpfp8pad78xj75pr"
|
||||||
@@ -958,7 +958,7 @@ exports[`components/integrations/AbstractIncomingWebhook should match snapshot,
|
|||||||
<input
|
<input
|
||||||
className="form-control"
|
className="form-control"
|
||||||
id="username"
|
id="username"
|
||||||
maxLength="22"
|
maxLength={22}
|
||||||
onChange={[Function]}
|
onChange={[Function]}
|
||||||
type="text"
|
type="text"
|
||||||
value=""
|
value=""
|
||||||
@@ -1057,7 +1057,7 @@ exports[`components/integrations/AbstractIncomingWebhook should match snapshot,
|
|||||||
<input
|
<input
|
||||||
className="form-control"
|
className="form-control"
|
||||||
id="displayName"
|
id="displayName"
|
||||||
maxLength="64"
|
maxLength={64}
|
||||||
onChange={[Function]}
|
onChange={[Function]}
|
||||||
type="text"
|
type="text"
|
||||||
value="testIncomingWebhook"
|
value="testIncomingWebhook"
|
||||||
@@ -1090,7 +1090,7 @@ exports[`components/integrations/AbstractIncomingWebhook should match snapshot,
|
|||||||
<input
|
<input
|
||||||
className="form-control"
|
className="form-control"
|
||||||
id="description"
|
id="description"
|
||||||
maxLength="500"
|
maxLength={500}
|
||||||
onChange={[Function]}
|
onChange={[Function]}
|
||||||
type="text"
|
type="text"
|
||||||
value="testing"
|
value="testing"
|
||||||
@@ -1121,8 +1121,8 @@ exports[`components/integrations/AbstractIncomingWebhook should match snapshot,
|
|||||||
className="col-md-5 col-sm-8"
|
className="col-md-5 col-sm-8"
|
||||||
>
|
>
|
||||||
<Connect(ChannelSelect)
|
<Connect(ChannelSelect)
|
||||||
id="channelId"
|
|
||||||
onChange={[Function]}
|
onChange={[Function]}
|
||||||
|
selectDm={false}
|
||||||
selectOpen={true}
|
selectOpen={true}
|
||||||
selectPrivate={true}
|
selectPrivate={true}
|
||||||
value="88cxd9wpzpbpfp8pad78xj75pr"
|
value="88cxd9wpzpbpfp8pad78xj75pr"
|
||||||
@@ -1186,7 +1186,7 @@ exports[`components/integrations/AbstractIncomingWebhook should match snapshot,
|
|||||||
<input
|
<input
|
||||||
className="form-control"
|
className="form-control"
|
||||||
id="iconURL"
|
id="iconURL"
|
||||||
maxLength="1024"
|
maxLength={1024}
|
||||||
onChange={[Function]}
|
onChange={[Function]}
|
||||||
type="text"
|
type="text"
|
||||||
value=""
|
value=""
|
||||||
@@ -1285,7 +1285,7 @@ exports[`components/integrations/AbstractIncomingWebhook should match snapshot,
|
|||||||
<input
|
<input
|
||||||
className="form-control"
|
className="form-control"
|
||||||
id="displayName"
|
id="displayName"
|
||||||
maxLength="64"
|
maxLength={64}
|
||||||
onChange={[Function]}
|
onChange={[Function]}
|
||||||
type="text"
|
type="text"
|
||||||
value="testIncomingWebhook"
|
value="testIncomingWebhook"
|
||||||
@@ -1318,7 +1318,7 @@ exports[`components/integrations/AbstractIncomingWebhook should match snapshot,
|
|||||||
<input
|
<input
|
||||||
className="form-control"
|
className="form-control"
|
||||||
id="description"
|
id="description"
|
||||||
maxLength="500"
|
maxLength={500}
|
||||||
onChange={[Function]}
|
onChange={[Function]}
|
||||||
type="text"
|
type="text"
|
||||||
value="testing"
|
value="testing"
|
||||||
@@ -1349,8 +1349,8 @@ exports[`components/integrations/AbstractIncomingWebhook should match snapshot,
|
|||||||
className="col-md-5 col-sm-8"
|
className="col-md-5 col-sm-8"
|
||||||
>
|
>
|
||||||
<Connect(ChannelSelect)
|
<Connect(ChannelSelect)
|
||||||
id="channelId"
|
|
||||||
onChange={[Function]}
|
onChange={[Function]}
|
||||||
|
selectDm={false}
|
||||||
selectOpen={true}
|
selectOpen={true}
|
||||||
selectPrivate={true}
|
selectPrivate={true}
|
||||||
value="88cxd9wpzpbpfp8pad78xj75pr"
|
value="88cxd9wpzpbpfp8pad78xj75pr"
|
||||||
@@ -1414,7 +1414,7 @@ exports[`components/integrations/AbstractIncomingWebhook should match snapshot,
|
|||||||
<input
|
<input
|
||||||
className="form-control"
|
className="form-control"
|
||||||
id="username"
|
id="username"
|
||||||
maxLength="22"
|
maxLength={22}
|
||||||
onChange={[Function]}
|
onChange={[Function]}
|
||||||
type="text"
|
type="text"
|
||||||
value=""
|
value=""
|
||||||
@@ -1447,7 +1447,7 @@ exports[`components/integrations/AbstractIncomingWebhook should match snapshot,
|
|||||||
<input
|
<input
|
||||||
className="form-control"
|
className="form-control"
|
||||||
id="iconURL"
|
id="iconURL"
|
||||||
maxLength="1024"
|
maxLength={1024}
|
||||||
onChange={[Function]}
|
onChange={[Function]}
|
||||||
type="text"
|
type="text"
|
||||||
value=""
|
value=""
|
||||||
|
|||||||
@@ -4,10 +4,28 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import {shallow} from 'enzyme';
|
import {shallow} from 'enzyme';
|
||||||
|
|
||||||
|
import ChannelSelect from 'components/channel_select';
|
||||||
|
|
||||||
import AbstractIncomingWebhook from 'components/integrations/abstract_incoming_webhook';
|
import AbstractIncomingWebhook from 'components/integrations/abstract_incoming_webhook';
|
||||||
|
import {Team} from '@mattermost/types/teams';
|
||||||
|
|
||||||
describe('components/integrations/AbstractIncomingWebhook', () => {
|
describe('components/integrations/AbstractIncomingWebhook', () => {
|
||||||
const team = {name: 'team_name'};
|
const team: Team = {id: 'team_id',
|
||||||
|
create_at: 0,
|
||||||
|
update_at: 0,
|
||||||
|
delete_at: 0,
|
||||||
|
display_name: 'team_name',
|
||||||
|
name: 'team_name',
|
||||||
|
description: 'team_description',
|
||||||
|
email: 'team_email',
|
||||||
|
type: 'I',
|
||||||
|
company_name: 'team_company_name',
|
||||||
|
allowed_domains: 'team_allowed_domains',
|
||||||
|
invite_id: 'team_invite_id',
|
||||||
|
allow_open_invite: false,
|
||||||
|
scheme_id: 'team_scheme_id',
|
||||||
|
group_constrained: false,
|
||||||
|
};
|
||||||
const header = {id: 'header_id', defaultMessage: 'Header'};
|
const header = {id: 'header_id', defaultMessage: 'Header'};
|
||||||
const footer = {id: 'footer_id', defaultMessage: 'Footer'};
|
const footer = {id: 'footer_id', defaultMessage: 'Footer'};
|
||||||
const loading = {id: 'loading_id', defaultMessage: 'Loading'};
|
const loading = {id: 'loading_id', defaultMessage: 'Loading'};
|
||||||
@@ -16,6 +34,15 @@ describe('components/integrations/AbstractIncomingWebhook', () => {
|
|||||||
display_name: 'testIncomingWebhook',
|
display_name: 'testIncomingWebhook',
|
||||||
channel_id: '88cxd9wpzpbpfp8pad78xj75pr',
|
channel_id: '88cxd9wpzpbpfp8pad78xj75pr',
|
||||||
description: 'testing',
|
description: 'testing',
|
||||||
|
id: 'test_id',
|
||||||
|
team_id: 'test_team_id',
|
||||||
|
create_at: 0,
|
||||||
|
update_at: 0,
|
||||||
|
delete_at: 0,
|
||||||
|
user_id: 'test_user_id',
|
||||||
|
username: '',
|
||||||
|
icon_url: '',
|
||||||
|
channel_locked: false,
|
||||||
};
|
};
|
||||||
const enablePostUsernameOverride = true;
|
const enablePostUsernameOverride = true;
|
||||||
const enablePostIconOverride = true;
|
const enablePostIconOverride = true;
|
||||||
@@ -104,7 +131,7 @@ describe('components/integrations/AbstractIncomingWebhook', () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const wrapper = shallow(<AbstractIncomingWebhook {...requiredProps}/>);
|
const wrapper = shallow(<AbstractIncomingWebhook {...requiredProps}/>);
|
||||||
wrapper.find('#channelId').simulate('change', evt);
|
wrapper.find(ChannelSelect).simulate('change', evt);
|
||||||
|
|
||||||
expect(wrapper.state('channelId')).toBe(newChannelId);
|
expect(wrapper.state('channelId')).toBe(newChannelId);
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,87 +1,100 @@
|
|||||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||||
// See LICENSE.txt for license information.
|
// See LICENSE.txt for license information.
|
||||||
|
|
||||||
import PropTypes from 'prop-types';
|
import React, {ChangeEventHandler, FormEvent, MouseEvent, PureComponent} from 'react';
|
||||||
import React from 'react';
|
import {FormattedMessage, MessageDescriptor} from 'react-intl';
|
||||||
import {FormattedMessage} from 'react-intl';
|
|
||||||
import {Link} from 'react-router-dom';
|
import {Link} from 'react-router-dom';
|
||||||
|
|
||||||
import BackstageHeader from 'components/backstage/components/backstage_header';
|
import BackstageHeader from 'components/backstage/components/backstage_header';
|
||||||
import ChannelSelect from 'components/channel_select';
|
import ChannelSelect from 'components/channel_select';
|
||||||
import FormError from 'components/form_error';
|
import FormError from 'components/form_error';
|
||||||
import SpinnerButton from 'components/spinner_button';
|
import SpinnerButton from 'components/spinner_button';
|
||||||
|
import {Team} from '@mattermost/types/teams';
|
||||||
import {localizeMessage} from 'utils/utils';
|
import {localizeMessage} from 'utils/utils';
|
||||||
|
import {IncomingWebhook} from '@mattermost/types/integrations';
|
||||||
|
|
||||||
export default class AbstractIncomingWebhook extends React.PureComponent {
|
interface State {
|
||||||
static propTypes = {
|
displayName: string;
|
||||||
|
description: string;
|
||||||
|
channelId: string;
|
||||||
|
channelLocked: boolean;
|
||||||
|
username: string;
|
||||||
|
iconURL: string;
|
||||||
|
saving: boolean;
|
||||||
|
serverError: string;
|
||||||
|
clientError: JSX.Element | null;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
interface Props {
|
||||||
* The current team
|
|
||||||
*/
|
|
||||||
team: PropTypes.object.isRequired,
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The header text to render, has id and defaultMessage
|
* The current team
|
||||||
*/
|
*/
|
||||||
header: PropTypes.object.isRequired,
|
team: Team;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The footer text to render, has id and defaultMessage
|
* The header text to render, has id and defaultMessage
|
||||||
*/
|
*/
|
||||||
footer: PropTypes.object.isRequired,
|
header: MessageDescriptor;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The spinner loading text to render, has id and defaultMessage
|
* The footer text to render, has id and defaultMessage
|
||||||
*/
|
*/
|
||||||
loading: PropTypes.object.isRequired,
|
footer: MessageDescriptor;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The server error text after a failed action
|
* The spinner loading text to render, has id and defaultMessage
|
||||||
*/
|
*/
|
||||||
serverError: PropTypes.string.isRequired,
|
loading: MessageDescriptor;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The hook used to set the initial state
|
* The server error text after a failed action
|
||||||
*/
|
*/
|
||||||
initialHook: PropTypes.object,
|
serverError: string;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Whether to allow configuration of the default post username.
|
* The hook used to set the initial state
|
||||||
*/
|
*/
|
||||||
enablePostUsernameOverride: PropTypes.bool.isRequired,
|
initialHook?: IncomingWebhook | Record<string, never>;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Whether to allow configuration of the default post icon.
|
* Whether to allow configuration of the default post username.
|
||||||
*/
|
*/
|
||||||
enablePostIconOverride: PropTypes.bool.isRequired,
|
enablePostUsernameOverride: boolean;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The async function to run when the action button is pressed
|
* Whether to allow configuration of the default post icon.
|
||||||
*/
|
*/
|
||||||
action: PropTypes.func.isRequired,
|
enablePostIconOverride: boolean;
|
||||||
}
|
|
||||||
|
|
||||||
constructor(props) {
|
/**
|
||||||
|
* The async function to run when the action button is pressed
|
||||||
|
*/
|
||||||
|
action: (hook: IncomingWebhook) => Promise<void>;
|
||||||
|
}
|
||||||
|
|
||||||
|
export default class AbstractIncomingWebhook extends PureComponent<Props, State> {
|
||||||
|
constructor(props: Props | Readonly<Props>) {
|
||||||
super(props);
|
super(props);
|
||||||
|
|
||||||
this.state = this.getStateFromHook(this.props.initialHook || {});
|
this.state = this.getStateFromHook(this.props.initialHook || {});
|
||||||
}
|
}
|
||||||
|
|
||||||
getStateFromHook = (hook) => {
|
getStateFromHook = (hook: IncomingWebhook | Record<string, never>) => {
|
||||||
return {
|
return {
|
||||||
displayName: hook.display_name || '',
|
displayName: hook?.display_name || '',
|
||||||
description: hook.description || '',
|
description: hook?.description || '',
|
||||||
channelId: hook.channel_id || '',
|
channelId: hook?.channel_id || '',
|
||||||
channelLocked: hook.channel_locked || false,
|
channelLocked: hook?.channel_locked || false,
|
||||||
username: hook.username || '',
|
username: hook?.username || '',
|
||||||
iconURL: hook.icon_url || '',
|
iconURL: hook?.icon_url || '',
|
||||||
saving: false,
|
saving: false,
|
||||||
serverError: '',
|
serverError: '',
|
||||||
clientError: null,
|
clientError: null,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
handleSubmit = (e) => {
|
handleSubmit = (e: MouseEvent<HTMLElement> | FormEvent<HTMLFormElement>) => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
|
|
||||||
if (this.state.saving) {
|
if (this.state.saving) {
|
||||||
@@ -91,7 +104,7 @@ export default class AbstractIncomingWebhook extends React.PureComponent {
|
|||||||
this.setState({
|
this.setState({
|
||||||
saving: true,
|
saving: true,
|
||||||
serverError: '',
|
serverError: '',
|
||||||
clientError: '',
|
clientError: null,
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!this.state.channelId) {
|
if (!this.state.channelId) {
|
||||||
@@ -115,50 +128,56 @@ export default class AbstractIncomingWebhook extends React.PureComponent {
|
|||||||
description: this.state.description,
|
description: this.state.description,
|
||||||
username: this.state.username,
|
username: this.state.username,
|
||||||
icon_url: this.state.iconURL,
|
icon_url: this.state.iconURL,
|
||||||
|
id: this.props.initialHook?.id || '',
|
||||||
|
create_at: this.props.initialHook?.create_at || 0,
|
||||||
|
update_at: this.props.initialHook?.update_at || 0,
|
||||||
|
delete_at: this.props.initialHook?.delete_at || 0,
|
||||||
|
team_id: this.props.initialHook?.team_id || '',
|
||||||
|
user_id: this.props.initialHook?.user_id || '',
|
||||||
};
|
};
|
||||||
|
|
||||||
this.props.action(hook).then(() => this.setState({saving: false}));
|
this.props.action(hook).then(() => this.setState({saving: false}));
|
||||||
}
|
}
|
||||||
|
|
||||||
updateDisplayName = (e) => {
|
updateDisplayName: ChangeEventHandler<HTMLInputElement> = (e) => {
|
||||||
this.setState({
|
this.setState({
|
||||||
displayName: e.target.value,
|
displayName: e.target.value,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
updateDescription = (e) => {
|
updateDescription: ChangeEventHandler<HTMLInputElement> = (e) => {
|
||||||
this.setState({
|
this.setState({
|
||||||
description: e.target.value,
|
description: e.target.value,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
updateChannelId = (e) => {
|
updateChannelId: ChangeEventHandler<HTMLSelectElement> = (e) => {
|
||||||
this.setState({
|
this.setState({
|
||||||
channelId: e.target.value,
|
channelId: e.target.value,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
updateChannelLocked = (e) => {
|
updateChannelLocked: ChangeEventHandler<HTMLInputElement> = (e) => {
|
||||||
this.setState({
|
this.setState({
|
||||||
channelLocked: e.target.checked,
|
channelLocked: e.target.checked,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
updateUsername = (e) => {
|
updateUsername: ChangeEventHandler<HTMLInputElement> = (e) => {
|
||||||
this.setState({
|
this.setState({
|
||||||
username: e.target.value,
|
username: e.target.value,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
updateIconURL = (e) => {
|
updateIconURL: ChangeEventHandler<HTMLInputElement> = (e) => {
|
||||||
this.setState({
|
this.setState({
|
||||||
iconURL: e.target.value,
|
iconURL: e.target.value,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
var headerToRender = this.props.header;
|
const headerToRender = this.props.header;
|
||||||
var footerToRender = this.props.footer;
|
const footerToRender = this.props.footer;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className='backstage-content'>
|
<div className='backstage-content'>
|
||||||
@@ -177,7 +196,7 @@ export default class AbstractIncomingWebhook extends React.PureComponent {
|
|||||||
<div className='backstage-form'>
|
<div className='backstage-form'>
|
||||||
<form
|
<form
|
||||||
className='form-horizontal'
|
className='form-horizontal'
|
||||||
onSubmit={this.handleSubmit}
|
onSubmit={(e) => this.handleSubmit(e)}
|
||||||
>
|
>
|
||||||
<div className='form-group'>
|
<div className='form-group'>
|
||||||
<label
|
<label
|
||||||
@@ -193,7 +212,7 @@ export default class AbstractIncomingWebhook extends React.PureComponent {
|
|||||||
<input
|
<input
|
||||||
id='displayName'
|
id='displayName'
|
||||||
type='text'
|
type='text'
|
||||||
maxLength='64'
|
maxLength={64}
|
||||||
className='form-control'
|
className='form-control'
|
||||||
value={this.state.displayName}
|
value={this.state.displayName}
|
||||||
onChange={this.updateDisplayName}
|
onChange={this.updateDisplayName}
|
||||||
@@ -220,7 +239,7 @@ export default class AbstractIncomingWebhook extends React.PureComponent {
|
|||||||
<input
|
<input
|
||||||
id='description'
|
id='description'
|
||||||
type='text'
|
type='text'
|
||||||
maxLength='500'
|
maxLength={500}
|
||||||
className='form-control'
|
className='form-control'
|
||||||
value={this.state.description}
|
value={this.state.description}
|
||||||
onChange={this.updateDescription}
|
onChange={this.updateDescription}
|
||||||
@@ -245,11 +264,11 @@ export default class AbstractIncomingWebhook extends React.PureComponent {
|
|||||||
</label>
|
</label>
|
||||||
<div className='col-md-5 col-sm-8'>
|
<div className='col-md-5 col-sm-8'>
|
||||||
<ChannelSelect
|
<ChannelSelect
|
||||||
id='channelId'
|
|
||||||
value={this.state.channelId}
|
value={this.state.channelId}
|
||||||
onChange={this.updateChannelId}
|
onChange={this.updateChannelId}
|
||||||
selectOpen={true}
|
selectOpen={true}
|
||||||
selectPrivate={true}
|
selectPrivate={true}
|
||||||
|
selectDm={false}
|
||||||
/>
|
/>
|
||||||
<div className='form__help'>
|
<div className='form__help'>
|
||||||
<FormattedMessage
|
<FormattedMessage
|
||||||
@@ -299,7 +318,7 @@ export default class AbstractIncomingWebhook extends React.PureComponent {
|
|||||||
<input
|
<input
|
||||||
id='username'
|
id='username'
|
||||||
type='text'
|
type='text'
|
||||||
maxLength='22'
|
maxLength={22}
|
||||||
className='form-control'
|
className='form-control'
|
||||||
value={this.state.username}
|
value={this.state.username}
|
||||||
onChange={this.updateUsername}
|
onChange={this.updateUsername}
|
||||||
@@ -328,7 +347,7 @@ export default class AbstractIncomingWebhook extends React.PureComponent {
|
|||||||
<input
|
<input
|
||||||
id='iconURL'
|
id='iconURL'
|
||||||
type='text'
|
type='text'
|
||||||
maxLength='1024'
|
maxLength={1024}
|
||||||
className='form-control'
|
className='form-control'
|
||||||
value={this.state.iconURL}
|
value={this.state.iconURL}
|
||||||
onChange={this.updateIconURL}
|
onChange={this.updateIconURL}
|
||||||
@@ -360,8 +379,8 @@ export default class AbstractIncomingWebhook extends React.PureComponent {
|
|||||||
className='btn btn-primary'
|
className='btn btn-primary'
|
||||||
type='submit'
|
type='submit'
|
||||||
spinning={this.state.saving}
|
spinning={this.state.saving}
|
||||||
spinningText={localizeMessage(this.props.loading.id, this.props.loading.defaultMessage)}
|
spinningText={localizeMessage(this.props.loading.id as string, this.props.loading.defaultMessage as string)}
|
||||||
onClick={this.handleSubmit}
|
onClick={(e) => this.handleSubmit(e)}
|
||||||
id='saveWebhook'
|
id='saveWebhook'
|
||||||
>
|
>
|
||||||
<FormattedMessage
|
<FormattedMessage
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||||
// See LICENSE.txt for license information.
|
// See LICENSE.txt for license information.
|
||||||
|
|
||||||
import React, {PureComponent, ReactNode} from 'react';
|
import React, {ButtonHTMLAttributes, PureComponent, ReactNode} from 'react';
|
||||||
|
|
||||||
import LoadingWrapper from 'components/widgets/loading/loading_wrapper';
|
import LoadingWrapper from 'components/widgets/loading/loading_wrapper';
|
||||||
|
|
||||||
@@ -9,10 +9,9 @@ type Props = {
|
|||||||
children?: ReactNode;
|
children?: ReactNode;
|
||||||
spinning: boolean;
|
spinning: boolean;
|
||||||
spinningText: ReactNode;
|
spinningText: ReactNode;
|
||||||
onClick?: (event: React.MouseEvent<HTMLButtonElement, MouseEvent>) => void;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export default class SpinnerButton extends PureComponent<Props & React.ButtonHTMLAttributes<HTMLButtonElement>> {
|
export default class SpinnerButton extends PureComponent<Props & ButtonHTMLAttributes<HTMLButtonElement>> {
|
||||||
public static defaultProps: Partial<Props> = {
|
public static defaultProps: Partial<Props> = {
|
||||||
spinning: false,
|
spinning: false,
|
||||||
}
|
}
|
||||||
|
|||||||
Ссылка в новой задаче
Block a user