Skip to content
This repository has been archived by the owner on Mar 13, 2024. It is now read-only.

Fixes #12456 : Migrate 'components/widgets/settings' module and associated tests to TypeScript #4061

Merged
merged 14 commits into from
Nov 11, 2019
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Migrated text settings and radio settings components of components/wi…
…dget/settings dir
  • Loading branch information
M-ZubairAhmed committed Oct 26, 2019
commit 13207a29a84fa9d6097901361f89d223ac5299a4
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import React from 'react';
import {shallow} from 'enzyme';

import RadioSetting from './radio_setting.jsx';
import RadioSetting from './radio_setting';

describe('components/widgets/settings/RadioSetting', () => {
test('render component with required props', () => {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,37 +1,34 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.

import PropTypes from 'prop-types';
import React from 'react';

import Setting from './setting';

export default class RadioSetting extends React.Component {
static propTypes = {
id: PropTypes.string.isRequired,
options: PropTypes.arrayOf(PropTypes.shape({
text: PropTypes.string,
value: PropTypes.string,
})),
label: PropTypes.node.isRequired,
onChange: PropTypes.func.isRequired,
value: PropTypes.string,
labelClassName: PropTypes.string,
inputClassName: PropTypes.string,
helpText: PropTypes.node,
};
type RadioSettingProps = {
id: string;
options: {text: string;value: string}[];
label: React.ReactNode;
onChange(name: string, value: any): void;
value?: string;
labelClassName?: string;
inputClassName?: string;
helpText?: React.ReactNode;

}

static defaultProps = {
export default class RadioSetting extends React.Component<RadioSettingProps> {
public static defaultProps = {
labelClassName: '',
inputClassName: '',
options: [],
};

handleChange = (e) => {
private handleChange: React.ChangeEventHandler<HTMLInputElement> = (e) => {
this.props.onChange(this.props.id, e.target.value);
}

render() {
public render() {
return (
<Setting
label={this.props.label}
Expand Down
2 changes: 1 addition & 1 deletion components/widgets/settings/setting.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

import React from 'react';

interface SettingsPropsInterface {
type SettingsPropsInterface = {
inputId?: string;
label: React.ReactNode;
labelClassName?: string;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,17 @@
import React from 'react';
import {shallow} from 'enzyme';

import TextSetting from './text_setting.jsx';
import TextSetting from './text_setting';

describe('components/widgets/settings/TextSetting', () => {
test('render component with required props', () => {
const onChange = jest.fn();
const wrapper = shallow(
<TextSetting
id='string.id'
label='some label'
value='some value'
onChange={onChange}
/>
);
expect(wrapper).toMatchInlineSnapshot(`
Expand All @@ -34,12 +36,14 @@ describe('components/widgets/settings/TextSetting', () => {
});

test('render with textarea type', () => {
const onChange = jest.fn();
const wrapper = shallow(
<TextSetting
id='string.id'
label='some label'
value='some value'
type='textarea'
onChange={onChange}
/>
);
expect(wrapper).toMatchInlineSnapshot(`
Expand All @@ -62,8 +66,10 @@ describe('components/widgets/settings/TextSetting', () => {
`);
});

// This test is disabled as TSC will not allow to pass any other value to `type`
/*
test('render with bad type', () => {
console.originalError = console.error;
const originalError = console.error;
console.error = jest.fn();

const wrapper = shallow(
Expand All @@ -77,7 +83,7 @@ describe('components/widgets/settings/TextSetting', () => {

expect(console.error).toBeCalledTimes(1);

console.error = console.originalError;
console.error = originalError;

expect(wrapper).toMatchInlineSnapshot(`
<Setting
Expand All @@ -97,6 +103,7 @@ describe('components/widgets/settings/TextSetting', () => {
</Setting>
`);
});
*/

test('onChange', () => {
const onChange = jest.fn();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,73 +1,65 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.

import PropTypes from 'prop-types';
import React from 'react';

import Setting from './setting';

export default class TextSetting extends React.Component {
static validTypes = [
'input',
'textarea',
'number',
'email',
'tel',
'url',
'password',
];
static propTypes = {
id: PropTypes.string.isRequired,
label: PropTypes.node.isRequired,
labelClassName: PropTypes.string,
placeholder: PropTypes.string,
helpText: PropTypes.node,
footer: PropTypes.node,
value: PropTypes.oneOfType([
PropTypes.string,
PropTypes.number,
]).isRequired,
inputClassName: PropTypes.string,
maxLength: PropTypes.number,
resizable: PropTypes.bool,
onChange: PropTypes.func,
disabled: PropTypes.bool,
type: PropTypes.oneOf(TextSetting.validTypes),
};
type InputTypes = 'input' |'textarea'| 'number'| 'email'| 'tel'| 'url'| 'password'
M-ZubairAhmed marked this conversation as resolved.
Show resolved Hide resolved

type TextSettingProps = {
id: string;
label: React.ReactNode;
labelClassName: string;
placeholder?: string;
helpText?: React.ReactNode;
footer?: React.ReactNode;
value: string | number;
inputClassName: string;
maxLength: number;
resizable: boolean;
onChange(name: string, value: any): void;
disabled?: boolean;
type: InputTypes;
}

// Since handle change is read from input and textarea element
type HandleChangeTypes = React.ChangeEventHandler<HTMLInputElement | HTMLTextAreaElement>

static defaultProps = {
export default class TextSetting extends React.Component<TextSettingProps> {
public static defaultProps = {
labelClassName: '',
inputClassName: '',
type: 'input',
maxLength: null,
resizable: true,
};

handleChange = (e) => {
private handleChange: HandleChangeTypes = (e) => {
if (this.props.type === 'number') {
this.props.onChange(this.props.id, parseInt(e.target.value, 10));
} else {
this.props.onChange(this.props.id, e.target.value);
}
}

render() {
public render() {
M-ZubairAhmed marked this conversation as resolved.
Show resolved Hide resolved
const {resizable} = this.props;
let {type} = this.props;
let input = null;

if (type === 'textarea') {
const style = {};
let style = {};
if (!resizable) {
style.resize = 'none';
style = Object.assign({}, {resize: 'none'});
}

input = (
<textarea
id={this.props.id}
style={style}
className='form-control'
rows='5'
rows={5}
placeholder={this.props.placeholder}
value={this.props.value}
maxLength={this.props.maxLength}
Expand Down
Loading