[MM-47094] Migrate "components/integrations/abstract_oauth_app.jsx" and tests to Typescript (#24529)
Этот коммит содержится в:
@@ -113,7 +113,7 @@ exports[`components/integrations/AbstractOAuthApp should match snapshot 1`] = `
|
|||||||
<input
|
<input
|
||||||
className="form-control"
|
className="form-control"
|
||||||
id="name"
|
id="name"
|
||||||
maxLength="64"
|
maxLength={64}
|
||||||
onChange={[Function]}
|
onChange={[Function]}
|
||||||
type="text"
|
type="text"
|
||||||
value="testApp"
|
value="testApp"
|
||||||
@@ -146,7 +146,7 @@ exports[`components/integrations/AbstractOAuthApp should match snapshot 1`] = `
|
|||||||
<input
|
<input
|
||||||
className="form-control"
|
className="form-control"
|
||||||
id="description"
|
id="description"
|
||||||
maxLength="512"
|
maxLength={512}
|
||||||
onChange={[Function]}
|
onChange={[Function]}
|
||||||
type="text"
|
type="text"
|
||||||
value="testing"
|
value="testing"
|
||||||
@@ -179,7 +179,7 @@ exports[`components/integrations/AbstractOAuthApp should match snapshot 1`] = `
|
|||||||
<input
|
<input
|
||||||
className="form-control"
|
className="form-control"
|
||||||
id="homepage"
|
id="homepage"
|
||||||
maxLength="256"
|
maxLength={256}
|
||||||
onChange={[Function]}
|
onChange={[Function]}
|
||||||
type="url"
|
type="url"
|
||||||
value="https://test.com"
|
value="https://test.com"
|
||||||
@@ -212,7 +212,7 @@ exports[`components/integrations/AbstractOAuthApp should match snapshot 1`] = `
|
|||||||
<input
|
<input
|
||||||
className="form-control"
|
className="form-control"
|
||||||
id="icon_url"
|
id="icon_url"
|
||||||
maxLength="512"
|
maxLength={512}
|
||||||
onChange={[Function]}
|
onChange={[Function]}
|
||||||
type="url"
|
type="url"
|
||||||
value="https://test.com/icon"
|
value="https://test.com/icon"
|
||||||
@@ -245,9 +245,9 @@ exports[`components/integrations/AbstractOAuthApp should match snapshot 1`] = `
|
|||||||
<textarea
|
<textarea
|
||||||
className="form-control"
|
className="form-control"
|
||||||
id="callbackUrls"
|
id="callbackUrls"
|
||||||
maxLength="1024"
|
maxLength={1024}
|
||||||
onChange={[Function]}
|
onChange={[Function]}
|
||||||
rows="3"
|
rows={3}
|
||||||
value="https://test.com/callback
|
value="https://test.com/callback
|
||||||
https://test.com/callback2"
|
https://test.com/callback2"
|
||||||
/>
|
/>
|
||||||
@@ -296,7 +296,9 @@ https://test.com/callback2"
|
|||||||
id="Footer"
|
id="Footer"
|
||||||
/>
|
/>
|
||||||
</SpinnerButton>
|
</SpinnerButton>
|
||||||
renderExtra
|
<div>
|
||||||
|
renderExtra
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
@@ -416,7 +418,7 @@ exports[`components/integrations/AbstractOAuthApp should match snapshot, display
|
|||||||
<input
|
<input
|
||||||
className="form-control"
|
className="form-control"
|
||||||
id="name"
|
id="name"
|
||||||
maxLength="64"
|
maxLength={64}
|
||||||
onChange={[Function]}
|
onChange={[Function]}
|
||||||
type="text"
|
type="text"
|
||||||
value="testApp"
|
value="testApp"
|
||||||
@@ -449,7 +451,7 @@ exports[`components/integrations/AbstractOAuthApp should match snapshot, display
|
|||||||
<input
|
<input
|
||||||
className="form-control"
|
className="form-control"
|
||||||
id="description"
|
id="description"
|
||||||
maxLength="512"
|
maxLength={512}
|
||||||
onChange={[Function]}
|
onChange={[Function]}
|
||||||
type="text"
|
type="text"
|
||||||
value="testing"
|
value="testing"
|
||||||
@@ -482,7 +484,7 @@ exports[`components/integrations/AbstractOAuthApp should match snapshot, display
|
|||||||
<input
|
<input
|
||||||
className="form-control"
|
className="form-control"
|
||||||
id="homepage"
|
id="homepage"
|
||||||
maxLength="256"
|
maxLength={256}
|
||||||
onChange={[Function]}
|
onChange={[Function]}
|
||||||
type="url"
|
type="url"
|
||||||
value="https://test.com"
|
value="https://test.com"
|
||||||
@@ -515,7 +517,7 @@ exports[`components/integrations/AbstractOAuthApp should match snapshot, display
|
|||||||
<input
|
<input
|
||||||
className="form-control"
|
className="form-control"
|
||||||
id="icon_url"
|
id="icon_url"
|
||||||
maxLength="512"
|
maxLength={512}
|
||||||
onChange={[Function]}
|
onChange={[Function]}
|
||||||
type="url"
|
type="url"
|
||||||
value="https://test.com/icon"
|
value="https://test.com/icon"
|
||||||
@@ -548,9 +550,9 @@ exports[`components/integrations/AbstractOAuthApp should match snapshot, display
|
|||||||
<textarea
|
<textarea
|
||||||
className="form-control"
|
className="form-control"
|
||||||
id="callbackUrls"
|
id="callbackUrls"
|
||||||
maxLength="1024"
|
maxLength={1024}
|
||||||
onChange={[Function]}
|
onChange={[Function]}
|
||||||
rows="3"
|
rows={3}
|
||||||
value=""
|
value=""
|
||||||
/>
|
/>
|
||||||
<div
|
<div
|
||||||
@@ -601,7 +603,9 @@ exports[`components/integrations/AbstractOAuthApp should match snapshot, display
|
|||||||
id="Footer"
|
id="Footer"
|
||||||
/>
|
/>
|
||||||
</SpinnerButton>
|
</SpinnerButton>
|
||||||
renderExtra
|
<div>
|
||||||
|
renderExtra
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
@@ -2,13 +2,14 @@
|
|||||||
// See LICENSE.txt for license information.
|
// See LICENSE.txt for license information.
|
||||||
|
|
||||||
import {shallow} from 'enzyme';
|
import {shallow} from 'enzyme';
|
||||||
import React from 'react';
|
import React, {type ChangeEvent} from 'react';
|
||||||
import {FormattedMessage} from 'react-intl';
|
import {FormattedMessage} from 'react-intl';
|
||||||
|
|
||||||
import AbstractOAuthApp from 'components/integrations/abstract_oauth_app.jsx';
|
import AbstractOAuthApp from 'components/integrations/abstract_oauth_app';
|
||||||
|
|
||||||
|
import {TestHelper} from 'utils/test_helper';
|
||||||
|
|
||||||
describe('components/integrations/AbstractOAuthApp', () => {
|
describe('components/integrations/AbstractOAuthApp', () => {
|
||||||
const team = {name: 'test'};
|
|
||||||
const header = {id: 'Header', defaultMessage: 'Header'};
|
const header = {id: 'Header', defaultMessage: 'Header'};
|
||||||
const footer = {id: 'Footer', defaultMessage: 'Footer'};
|
const footer = {id: 'Footer', defaultMessage: 'Footer'};
|
||||||
const loading = {id: 'Loading', defaultMessage: 'Loading'};
|
const loading = {id: 'Loading', defaultMessage: 'Loading'};
|
||||||
@@ -25,19 +26,23 @@ describe('components/integrations/AbstractOAuthApp', () => {
|
|||||||
update_at: 1501365458934,
|
update_at: 1501365458934,
|
||||||
callback_urls: ['https://test.com/callback', 'https://test.com/callback2'],
|
callback_urls: ['https://test.com/callback', 'https://test.com/callback2'],
|
||||||
};
|
};
|
||||||
|
|
||||||
const action = jest.fn().mockImplementation(
|
const action = jest.fn().mockImplementation(
|
||||||
() => {
|
() => {
|
||||||
return new Promise((resolve) => {
|
return new Promise<void>((resolve) => {
|
||||||
process.nextTick(() => resolve());
|
process.nextTick(() => resolve());
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const team = TestHelper.getTeamMock({name: 'test', id: initialApp.id});
|
||||||
|
|
||||||
const baseProps = {
|
const baseProps = {
|
||||||
team,
|
team,
|
||||||
header,
|
header,
|
||||||
footer,
|
footer,
|
||||||
loading,
|
loading,
|
||||||
renderExtra: 'renderExtra',
|
renderExtra: <div>{'renderExtra'}</div>,
|
||||||
serverError: '',
|
serverError: '',
|
||||||
initialApp,
|
initialApp,
|
||||||
action: jest.fn(),
|
action: jest.fn(),
|
||||||
@@ -82,81 +87,89 @@ describe('components/integrations/AbstractOAuthApp', () => {
|
|||||||
|
|
||||||
test('should have correct state when updateName is called', () => {
|
test('should have correct state when updateName is called', () => {
|
||||||
const props = {...baseProps, action};
|
const props = {...baseProps, action};
|
||||||
const wrapper = shallow(
|
const wrapper = shallow<AbstractOAuthApp>(
|
||||||
<AbstractOAuthApp {...props}/>,
|
<AbstractOAuthApp {...props}/>,
|
||||||
);
|
);
|
||||||
|
const evt = {preventDefault: jest.fn(), target: {value: 'new name'}} as unknown as ChangeEvent<HTMLInputElement>;
|
||||||
wrapper.instance().updateName({target: {value: 'new name'}});
|
wrapper.instance().updateName(evt);
|
||||||
expect(wrapper.state('name')).toEqual('new name');
|
expect(wrapper.state('name')).toEqual('new name');
|
||||||
|
const evt2 = {preventDefault: jest.fn(), target: {value: 'another name'}} as unknown as ChangeEvent<HTMLInputElement>;
|
||||||
wrapper.instance().updateName({target: {value: 'other name'}});
|
wrapper.instance().updateName(evt2);
|
||||||
expect(wrapper.state('name')).toEqual('other name');
|
expect(wrapper.state('name')).toEqual('another name');
|
||||||
});
|
});
|
||||||
|
|
||||||
test('should have correct state when updateTrusted is called', () => {
|
test('should have correct state when updateTrusted is called', () => {
|
||||||
const props = {...baseProps, action};
|
const props = {...baseProps, action};
|
||||||
const wrapper = shallow(
|
const wrapper = shallow<AbstractOAuthApp>(
|
||||||
<AbstractOAuthApp {...props}/>,
|
<AbstractOAuthApp {...props}/>,
|
||||||
);
|
);
|
||||||
|
|
||||||
wrapper.instance().updateTrusted({target: {value: 'false'}});
|
const evt = {preventDefault: jest.fn(), target: {value: 'false'}} as unknown as ChangeEvent<HTMLInputElement>;
|
||||||
|
wrapper.instance().updateTrusted(evt);
|
||||||
expect(wrapper.state('is_trusted')).toEqual(false);
|
expect(wrapper.state('is_trusted')).toEqual(false);
|
||||||
|
|
||||||
wrapper.instance().updateTrusted({target: {value: 'true'}});
|
const evt2 = {preventDefault: jest.fn(), target: {value: 'true'}} as unknown as ChangeEvent<HTMLInputElement>;
|
||||||
|
wrapper.instance().updateTrusted(evt2);
|
||||||
expect(wrapper.state('is_trusted')).toEqual(true);
|
expect(wrapper.state('is_trusted')).toEqual(true);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('should have correct state when updateDescription is called', () => {
|
test('should have correct state when updateDescription is called', () => {
|
||||||
const props = {...baseProps, action};
|
const props = {...baseProps, action};
|
||||||
const wrapper = shallow(
|
const wrapper = shallow<AbstractOAuthApp>(
|
||||||
<AbstractOAuthApp {...props}/>,
|
<AbstractOAuthApp {...props}/>,
|
||||||
);
|
);
|
||||||
|
|
||||||
wrapper.instance().updateDescription({target: {value: 'new description'}});
|
const evt = {preventDefault: jest.fn(), target: {value: 'new description'}} as unknown as ChangeEvent<HTMLInputElement>;
|
||||||
|
wrapper.instance().updateDescription(evt);
|
||||||
expect(wrapper.state('description')).toEqual('new description');
|
expect(wrapper.state('description')).toEqual('new description');
|
||||||
|
|
||||||
wrapper.instance().updateDescription({target: {value: 'another description'}});
|
const evt2 = {preventDefault: jest.fn(), target: {value: 'another description'}} as unknown as ChangeEvent<HTMLInputElement>;
|
||||||
|
wrapper.instance().updateDescription(evt2);
|
||||||
expect(wrapper.state('description')).toEqual('another description');
|
expect(wrapper.state('description')).toEqual('another description');
|
||||||
});
|
});
|
||||||
|
|
||||||
test('should have correct state when updateHomepage is called', () => {
|
test('should have correct state when updateHomepage is called', () => {
|
||||||
const props = {...baseProps, action};
|
const props = {...baseProps, action};
|
||||||
const wrapper = shallow(
|
const wrapper = shallow<AbstractOAuthApp>(
|
||||||
<AbstractOAuthApp {...props}/>,
|
<AbstractOAuthApp {...props}/>,
|
||||||
);
|
);
|
||||||
|
|
||||||
wrapper.instance().updateHomepage({target: {value: 'new homepage'}});
|
const evt = {preventDefault: jest.fn(), target: {value: 'new homepage'}} as unknown as ChangeEvent<HTMLInputElement>;
|
||||||
|
wrapper.instance().updateHomepage(evt);
|
||||||
expect(wrapper.state('homepage')).toEqual('new homepage');
|
expect(wrapper.state('homepage')).toEqual('new homepage');
|
||||||
|
|
||||||
wrapper.instance().updateHomepage({target: {value: 'another homepage'}});
|
const evt2 = {preventDefault: jest.fn(), target: {value: 'another homepage'}} as unknown as ChangeEvent<HTMLInputElement>;
|
||||||
|
wrapper.instance().updateHomepage(evt2);
|
||||||
expect(wrapper.state('homepage')).toEqual('another homepage');
|
expect(wrapper.state('homepage')).toEqual('another homepage');
|
||||||
});
|
});
|
||||||
|
|
||||||
test('should have correct state when updateIconUrl is called', () => {
|
test('should have correct state when updateIconUrl is called', () => {
|
||||||
const props = {...baseProps, action};
|
const props = {...baseProps, action};
|
||||||
const wrapper = shallow(
|
const wrapper = shallow<AbstractOAuthApp>(
|
||||||
<AbstractOAuthApp {...props}/>,
|
<AbstractOAuthApp {...props}/>,
|
||||||
);
|
);
|
||||||
|
|
||||||
wrapper.setState({has_icon: true});
|
wrapper.setState({has_icon: true});
|
||||||
wrapper.instance().updateIconUrl({target: {value: 'https://test.com/new_icon_url'}});
|
const evt = {preventDefault: jest.fn(), target: {value: 'https://test.com/new_icon_url'}} as unknown as ChangeEvent<HTMLInputElement>;
|
||||||
|
wrapper.instance().updateIconUrl(evt);
|
||||||
expect(wrapper.state('icon_url')).toEqual('https://test.com/new_icon_url');
|
expect(wrapper.state('icon_url')).toEqual('https://test.com/new_icon_url');
|
||||||
expect(wrapper.state('has_icon')).toEqual(false);
|
expect(wrapper.state('has_icon')).toEqual(false);
|
||||||
|
|
||||||
wrapper.setState({has_icon: true});
|
wrapper.setState({has_icon: true});
|
||||||
wrapper.instance().updateIconUrl({target: {value: 'https://test.com/another_icon_url'}});
|
const evt2 = {preventDefault: jest.fn(), target: {value: 'https://test.com/another_icon_url'}} as unknown as ChangeEvent<HTMLInputElement>;
|
||||||
|
wrapper.instance().updateIconUrl(evt2);
|
||||||
expect(wrapper.state('icon_url')).toEqual('https://test.com/another_icon_url');
|
expect(wrapper.state('icon_url')).toEqual('https://test.com/another_icon_url');
|
||||||
expect(wrapper.state('has_icon')).toEqual(false);
|
expect(wrapper.state('has_icon')).toEqual(false);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('should have correct state when handleSubmit is called', () => {
|
test('should have correct state when handleSubmit is called', () => {
|
||||||
const props = {...baseProps, action};
|
const props = {...baseProps, action};
|
||||||
const wrapper = shallow(
|
const wrapper = shallow<AbstractOAuthApp>(
|
||||||
<AbstractOAuthApp {...props}/>,
|
<AbstractOAuthApp {...props}/>,
|
||||||
);
|
);
|
||||||
|
|
||||||
const newState = {saving: false, name: 'name', description: 'description', homepage: 'homepage'};
|
const newState = {saving: false, name: 'name', description: 'description', homepage: 'homepage'};
|
||||||
const evt = {preventDefault: jest.fn()};
|
const evt = {preventDefault: jest.fn()} as any;
|
||||||
wrapper.setState({saving: true});
|
wrapper.setState({saving: true});
|
||||||
wrapper.instance().handleSubmit(evt);
|
wrapper.instance().handleSubmit(evt);
|
||||||
expect(evt.preventDefault).toHaveBeenCalled();
|
expect(evt.preventDefault).toHaveBeenCalled();
|
||||||
@@ -1,11 +1,15 @@
|
|||||||
// 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 type {ChangeEvent, FormEvent} from 'react';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import {FormattedMessage} from 'react-intl';
|
import {FormattedMessage} from 'react-intl';
|
||||||
|
import type {MessageDescriptor} from 'react-intl';
|
||||||
import {Link} from 'react-router-dom';
|
import {Link} from 'react-router-dom';
|
||||||
|
|
||||||
|
import type {OAuthApp} from '@mattermost/types/integrations';
|
||||||
|
import type {Team} from '@mattermost/types/teams';
|
||||||
|
|
||||||
import {Permissions} from 'mattermost-redux/constants';
|
import {Permissions} from 'mattermost-redux/constants';
|
||||||
|
|
||||||
import BackstageHeader from 'components/backstage/components/backstage_header';
|
import BackstageHeader from 'components/backstage/components/backstage_header';
|
||||||
@@ -15,60 +19,76 @@ import SpinnerButton from 'components/spinner_button';
|
|||||||
|
|
||||||
import {localizeMessage} from 'utils/utils';
|
import {localizeMessage} from 'utils/utils';
|
||||||
|
|
||||||
export default class AbstractOAuthApp extends React.PureComponent {
|
type Props = {
|
||||||
static propTypes = {
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The current team
|
* The current team
|
||||||
*/
|
*/
|
||||||
team: PropTypes.object.isRequired,
|
team: Team;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The header text to render, has id and defaultMessage
|
* The header text to render, has id and defaultMessage
|
||||||
*/
|
*/
|
||||||
header: PropTypes.object.isRequired,
|
header: MessageDescriptor;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The footer text to render, has id and defaultMessage
|
* The footer text to render, has id and defaultMessage
|
||||||
*/
|
*/
|
||||||
footer: PropTypes.object.isRequired,
|
footer: MessageDescriptor;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The spinner loading text to render, has id and defaultMessage
|
* The spinner loading text to render, has id and defaultMessage
|
||||||
*/
|
*/
|
||||||
loading: PropTypes.object.isRequired,
|
loading: MessageDescriptor;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Any extra component/node to render
|
* Any extra component/node to render
|
||||||
*/
|
*/
|
||||||
renderExtra: PropTypes.node.isRequired,
|
renderExtra?: JSX.Element;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The server error text after a failed action
|
* The server error text after a failed action
|
||||||
*/
|
*/
|
||||||
serverError: PropTypes.string.isRequired,
|
serverError: string;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The OAuthApp used to set the initial state
|
* The OAuthApp used to set the initial state
|
||||||
*/
|
*/
|
||||||
initialApp: PropTypes.object,
|
initialApp?: OAuthApp;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The async function to run when the action button is pressed
|
* The async function to run when the action button is pressed
|
||||||
*/
|
*/
|
||||||
action: PropTypes.func.isRequired,
|
action: (app: OAuthApp) => Promise<void>;
|
||||||
};
|
|
||||||
|
|
||||||
constructor(props) {
|
}
|
||||||
|
|
||||||
|
type State = {
|
||||||
|
name: string;
|
||||||
|
description: string;
|
||||||
|
homepage: string;
|
||||||
|
icon_url: string;
|
||||||
|
callbackUrls: string;
|
||||||
|
is_trusted: boolean;
|
||||||
|
has_icon: boolean;
|
||||||
|
saving: boolean;
|
||||||
|
clientError: JSX.Element | null | string;
|
||||||
|
};
|
||||||
|
|
||||||
|
export default class AbstractOAuthApp extends React.PureComponent<Props, State> {
|
||||||
|
private image: HTMLImageElement;
|
||||||
|
private icon_url: React.RefObject<HTMLInputElement>;
|
||||||
|
|
||||||
|
constructor(props: Props) {
|
||||||
super(props);
|
super(props);
|
||||||
|
|
||||||
this.image = new Image();
|
this.image = new Image();
|
||||||
this.image.onload = this.imageLoaded;
|
this.image.onload = this.imageLoaded;
|
||||||
this.icon_url = React.createRef();
|
this.icon_url = React.createRef();
|
||||||
this.state = this.getStateFromApp(this.props.initialApp || {});
|
this.state = this.getStateFromApp(this.props.initialApp || {} as OAuthApp);
|
||||||
}
|
}
|
||||||
|
|
||||||
getStateFromApp = (app) => {
|
getStateFromApp = (app: OAuthApp) => {
|
||||||
return {
|
return {
|
||||||
name: app.name || '',
|
name: app.name || '',
|
||||||
description: app.description || '',
|
description: app.description || '',
|
||||||
@@ -83,13 +103,15 @@ export default class AbstractOAuthApp extends React.PureComponent {
|
|||||||
};
|
};
|
||||||
|
|
||||||
imageLoaded = () => {
|
imageLoaded = () => {
|
||||||
this.setState({
|
if (this.icon_url.current?.value) {
|
||||||
has_icon: true,
|
this.setState({
|
||||||
icon_url: this.icon_url.current.value,
|
has_icon: true,
|
||||||
});
|
icon_url: this.icon_url.current.value,
|
||||||
|
});
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
handleSubmit = (e) => {
|
handleSubmit = (e: FormEvent) => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
|
|
||||||
if (this.state.saving) {
|
if (this.state.saving) {
|
||||||
@@ -173,36 +195,36 @@ export default class AbstractOAuthApp extends React.PureComponent {
|
|||||||
description: this.state.description,
|
description: this.state.description,
|
||||||
is_trusted: this.state.is_trusted,
|
is_trusted: this.state.is_trusted,
|
||||||
icon_url: this.state.icon_url,
|
icon_url: this.state.icon_url,
|
||||||
};
|
} as OAuthApp;
|
||||||
|
|
||||||
this.props.action(app).then(() => this.setState({saving: false}));
|
this.props.action(app).then(() => this.setState({saving: false}));
|
||||||
};
|
};
|
||||||
|
|
||||||
updateName = (e) => {
|
updateName = (e: ChangeEvent<HTMLInputElement>) => {
|
||||||
this.setState({
|
this.setState({
|
||||||
name: e.target.value,
|
name: e.target.value,
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
updateTrusted = (e) => {
|
updateTrusted = (e: ChangeEvent<HTMLInputElement>) => {
|
||||||
this.setState({
|
this.setState({
|
||||||
is_trusted: e.target.value === 'true',
|
is_trusted: e.target.value === 'true',
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
updateDescription = (e) => {
|
updateDescription = (e: ChangeEvent<HTMLInputElement>) => {
|
||||||
this.setState({
|
this.setState({
|
||||||
description: e.target.value,
|
description: e.target.value,
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
updateHomepage = (e) => {
|
updateHomepage = (e: ChangeEvent<HTMLInputElement>) => {
|
||||||
this.setState({
|
this.setState({
|
||||||
homepage: e.target.value,
|
homepage: e.target.value,
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
updateIconUrl = (e) => {
|
updateIconUrl = (e: ChangeEvent<HTMLInputElement>) => {
|
||||||
this.setState({
|
this.setState({
|
||||||
has_icon: false,
|
has_icon: false,
|
||||||
icon_url: e.target.value,
|
icon_url: e.target.value,
|
||||||
@@ -210,7 +232,7 @@ export default class AbstractOAuthApp extends React.PureComponent {
|
|||||||
this.image.src = e.target.value;
|
this.image.src = e.target.value;
|
||||||
};
|
};
|
||||||
|
|
||||||
updateCallbackUrls = (e) => {
|
updateCallbackUrls = (e: ChangeEvent<HTMLTextAreaElement>) => {
|
||||||
this.setState({
|
this.setState({
|
||||||
callbackUrls: e.target.value,
|
callbackUrls: e.target.value,
|
||||||
});
|
});
|
||||||
@@ -315,7 +337,7 @@ export default class AbstractOAuthApp extends React.PureComponent {
|
|||||||
<input
|
<input
|
||||||
id='name'
|
id='name'
|
||||||
type='text'
|
type='text'
|
||||||
maxLength='64'
|
maxLength={64}
|
||||||
className='form-control'
|
className='form-control'
|
||||||
value={this.state.name}
|
value={this.state.name}
|
||||||
onChange={this.updateName}
|
onChange={this.updateName}
|
||||||
@@ -342,7 +364,7 @@ export default class AbstractOAuthApp extends React.PureComponent {
|
|||||||
<input
|
<input
|
||||||
id='description'
|
id='description'
|
||||||
type='text'
|
type='text'
|
||||||
maxLength='512'
|
maxLength={512}
|
||||||
className='form-control'
|
className='form-control'
|
||||||
value={this.state.description}
|
value={this.state.description}
|
||||||
onChange={this.updateDescription}
|
onChange={this.updateDescription}
|
||||||
@@ -369,7 +391,7 @@ export default class AbstractOAuthApp extends React.PureComponent {
|
|||||||
<input
|
<input
|
||||||
id='homepage'
|
id='homepage'
|
||||||
type='url'
|
type='url'
|
||||||
maxLength='256'
|
maxLength={256}
|
||||||
className='form-control'
|
className='form-control'
|
||||||
value={this.state.homepage}
|
value={this.state.homepage}
|
||||||
onChange={this.updateHomepage}
|
onChange={this.updateHomepage}
|
||||||
@@ -397,7 +419,7 @@ export default class AbstractOAuthApp extends React.PureComponent {
|
|||||||
id='icon_url'
|
id='icon_url'
|
||||||
ref={this.icon_url}
|
ref={this.icon_url}
|
||||||
type='url'
|
type='url'
|
||||||
maxLength='512'
|
maxLength={512}
|
||||||
className='form-control'
|
className='form-control'
|
||||||
value={this.state.icon_url}
|
value={this.state.icon_url}
|
||||||
onChange={this.updateIconUrl}
|
onChange={this.updateIconUrl}
|
||||||
@@ -423,8 +445,8 @@ export default class AbstractOAuthApp extends React.PureComponent {
|
|||||||
<div className='col-md-5 col-sm-8'>
|
<div className='col-md-5 col-sm-8'>
|
||||||
<textarea
|
<textarea
|
||||||
id='callbackUrls'
|
id='callbackUrls'
|
||||||
rows='3'
|
rows={3}
|
||||||
maxLength='1024'
|
maxLength={1024}
|
||||||
className='form-control'
|
className='form-control'
|
||||||
value={this.state.callbackUrls}
|
value={this.state.callbackUrls}
|
||||||
onChange={this.updateCallbackUrls}
|
onChange={this.updateCallbackUrls}
|
||||||
@@ -455,7 +477,7 @@ export default class AbstractOAuthApp 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 || '', (this.props.loading?.defaultMessage || '') as string)}
|
||||||
onClick={this.handleSubmit}
|
onClick={this.handleSubmit}
|
||||||
id='saveOauthApp'
|
id='saveOauthApp'
|
||||||
>
|
>
|
||||||
@@ -21,7 +21,6 @@ exports[`components/integrations/AddOAuthApp should match snapshot 1`] = `
|
|||||||
"id": "installed_oauth_apps.saving",
|
"id": "installed_oauth_apps.saving",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
renderExtra=""
|
|
||||||
serverError=""
|
serverError=""
|
||||||
team={
|
team={
|
||||||
Object {
|
Object {
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ import type {ActionResult} from 'mattermost-redux/types/actions.js';
|
|||||||
|
|
||||||
import {t} from 'utils/i18n';
|
import {t} from 'utils/i18n';
|
||||||
|
|
||||||
import AbstractOAuthApp from '../abstract_oauth_app.jsx';
|
import AbstractOAuthApp from '../abstract_oauth_app';
|
||||||
|
|
||||||
const HEADER = {id: t('add_oauth_app.header'), defaultMessage: 'Add'};
|
const HEADER = {id: t('add_oauth_app.header'), defaultMessage: 'Add'};
|
||||||
const FOOTER = {id: t('installed_oauth_apps.save'), defaultMessage: 'Save'};
|
const FOOTER = {id: t('installed_oauth_apps.save'), defaultMessage: 'Save'};
|
||||||
@@ -58,7 +58,6 @@ const AddOAuthApp = ({team, actions}: Props): JSX.Element => {
|
|||||||
header={HEADER}
|
header={HEADER}
|
||||||
footer={FOOTER}
|
footer={FOOTER}
|
||||||
loading={LOADING}
|
loading={LOADING}
|
||||||
renderExtra={''}
|
|
||||||
action={addOAuthApp}
|
action={addOAuthApp}
|
||||||
serverError={serverError}
|
serverError={serverError}
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ import LoadingScreen from 'components/loading_screen';
|
|||||||
|
|
||||||
import {getHistory} from 'utils/browser_history';
|
import {getHistory} from 'utils/browser_history';
|
||||||
|
|
||||||
import AbstractOAuthApp from '../abstract_oauth_app.jsx';
|
import AbstractOAuthApp from '../abstract_oauth_app';
|
||||||
|
|
||||||
const HEADER = {id: 'integrations.edit', defaultMessage: 'Edit'};
|
const HEADER = {id: 'integrations.edit', defaultMessage: 'Edit'};
|
||||||
const FOOTER = {id: 'update_incoming_webhook.update', defaultMessage: 'Update'};
|
const FOOTER = {id: 'update_incoming_webhook.update', defaultMessage: 'Update'};
|
||||||
|
|||||||
Ссылка в новой задаче
Block a user