converted migrations_table class component to functional component (#27956)
* converted migrations_table class component to functional component * added dependencylist for useffect & use memo for caching * Added tests * Remove commented code and used renderWithContext instead of render(withIntl(..)) --------- Co-authored-by: Ezekiel <ezekiel@itsmart.my> Co-authored-by: Mattermost Build <build@mattermost.com>
Этот коммит содержится в:
@@ -381,7 +381,7 @@ exports[`components/DatabaseSettings should match snapshot 1`] = `
|
|||||||
<div
|
<div
|
||||||
className="migrations-table-setting"
|
className="migrations-table-setting"
|
||||||
>
|
>
|
||||||
<Connect(MigrationsTable)
|
<Connect(Component)
|
||||||
createHelpText={
|
createHelpText={
|
||||||
<Memo(MemoizedFormattedMessage)
|
<Memo(MemoizedFormattedMessage)
|
||||||
defaultMessage="All applied migrations."
|
defaultMessage="All applied migrations."
|
||||||
|
|||||||
@@ -0,0 +1,42 @@
|
|||||||
|
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||||
|
|
||||||
|
exports[`components/MigrationsTable should match snapshot when there are no migrations 1`] = `
|
||||||
|
<div
|
||||||
|
className="MigrationsTable migrations-table__panel"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
className="help-text"
|
||||||
|
>
|
||||||
|
<MemoizedFormattedMessage
|
||||||
|
defaultMessage="All applied migrations."
|
||||||
|
id="admin.database.migrations_table.help_text"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
className="migrations-table__table"
|
||||||
|
>
|
||||||
|
<table
|
||||||
|
className="table"
|
||||||
|
data-testid="migrationsTable"
|
||||||
|
>
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>
|
||||||
|
<MemoizedFormattedMessage
|
||||||
|
defaultMessage="Version"
|
||||||
|
id="admin.database.migrations_table.version"
|
||||||
|
/>
|
||||||
|
</th>
|
||||||
|
<th>
|
||||||
|
<MemoizedFormattedMessage
|
||||||
|
defaultMessage="Name"
|
||||||
|
id="admin.database.migrations_table.name"
|
||||||
|
/>
|
||||||
|
</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody />
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
@@ -0,0 +1,79 @@
|
|||||||
|
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||||
|
// See LICENSE.txt for license information.
|
||||||
|
|
||||||
|
import {act, screen, waitFor} from '@testing-library/react';
|
||||||
|
import {shallow} from 'enzyme';
|
||||||
|
import React from 'react';
|
||||||
|
import {FormattedMessage} from 'react-intl';
|
||||||
|
|
||||||
|
import type {SchemaMigration} from '@mattermost/types/admin';
|
||||||
|
|
||||||
|
import type {ActionResult} from 'mattermost-redux/types/actions';
|
||||||
|
|
||||||
|
import {renderWithContext} from 'tests/react_testing_utils';
|
||||||
|
|
||||||
|
import MigrationsTable from './migrations_table';
|
||||||
|
|
||||||
|
const migrationsMockData: SchemaMigration[] = [];
|
||||||
|
|
||||||
|
describe('components/MigrationsTable', () => {
|
||||||
|
const createHelpText = (
|
||||||
|
<FormattedMessage
|
||||||
|
id='admin.database.migrations_table.help_text'
|
||||||
|
defaultMessage='All applied migrations.'
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
|
||||||
|
const baseProps = {
|
||||||
|
createHelpText,
|
||||||
|
className: '',
|
||||||
|
actions: {
|
||||||
|
getAppliedSchemaMigrations: (jest.fn()).mockResolvedValue({
|
||||||
|
data: migrationsMockData,
|
||||||
|
} as ActionResult),
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
test('should match snapshot when there are no migrations', () => {
|
||||||
|
const wrapper = shallow(
|
||||||
|
<MigrationsTable
|
||||||
|
{...baseProps}
|
||||||
|
/>);
|
||||||
|
|
||||||
|
expect(wrapper).toMatchSnapshot();
|
||||||
|
});
|
||||||
|
|
||||||
|
test('should have called actions.getAppliedSchemaMigrations only when first rendered', async () => {
|
||||||
|
const mockMigrations = [
|
||||||
|
{version: '1.0', name: 'Initial migration'},
|
||||||
|
{version: '1.1', name: 'Add users table'},
|
||||||
|
];
|
||||||
|
const withDataProps = {
|
||||||
|
...baseProps,
|
||||||
|
actions: {
|
||||||
|
getAppliedSchemaMigrations: (jest.fn()).mockResolvedValue({
|
||||||
|
data: mockMigrations,
|
||||||
|
} as ActionResult),
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
const view = renderWithContext(<MigrationsTable {...withDataProps}/>);
|
||||||
|
|
||||||
|
await waitFor(() => {
|
||||||
|
expect(withDataProps.actions.getAppliedSchemaMigrations).toHaveBeenCalledTimes(1);
|
||||||
|
});
|
||||||
|
|
||||||
|
act(() => {
|
||||||
|
const newProps = {...withDataProps, className: 'foo'};
|
||||||
|
view.rerender(<MigrationsTable {...newProps}/>);
|
||||||
|
});
|
||||||
|
|
||||||
|
await waitFor(() => {
|
||||||
|
expect(withDataProps.actions.getAppliedSchemaMigrations).toHaveBeenCalledTimes(1);
|
||||||
|
mockMigrations.forEach((migration) => {
|
||||||
|
expect(screen.getByText(migration.version)).toBeInTheDocument();
|
||||||
|
expect(screen.getByText(migration.name)).toBeInTheDocument();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -2,7 +2,7 @@
|
|||||||
// See LICENSE.txt for license information.
|
// See LICENSE.txt for license information.
|
||||||
|
|
||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
import React from 'react';
|
import React, {useEffect, useMemo, useState} from 'react';
|
||||||
import {FormattedMessage} from 'react-intl';
|
import {FormattedMessage} from 'react-intl';
|
||||||
|
|
||||||
import type {SchemaMigration} from '@mattermost/types/admin';
|
import type {SchemaMigration} from '@mattermost/types/admin';
|
||||||
@@ -11,7 +11,7 @@ import type {ActionResult} from 'mattermost-redux/types/actions';
|
|||||||
|
|
||||||
import './migrations_table.scss';
|
import './migrations_table.scss';
|
||||||
|
|
||||||
export type Props = {
|
type Props = {
|
||||||
createHelpText: React.ReactElement;
|
createHelpText: React.ReactElement;
|
||||||
className?: string;
|
className?: string;
|
||||||
actions: {
|
actions: {
|
||||||
@@ -19,72 +19,68 @@ export type Props = {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
type State = {
|
const MigrationsTable = ({
|
||||||
migrations: SchemaMigration[];
|
createHelpText,
|
||||||
}
|
className,
|
||||||
|
actions,
|
||||||
|
}: Props) => {
|
||||||
|
const [migrations, setMigrations] = useState<SchemaMigration[]>([]);
|
||||||
|
|
||||||
class MigrationsTable extends React.PureComponent<Props, State> {
|
useEffect(() => {
|
||||||
constructor(props: Props) {
|
async function handleGetAppliedSchemaMigrations() {
|
||||||
super(props);
|
const result: ActionResult = await actions.getAppliedSchemaMigrations();
|
||||||
this.state = {
|
if (result.data) {
|
||||||
migrations: [],
|
setMigrations(result.data);
|
||||||
};
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
componentDidMount() {
|
handleGetAppliedSchemaMigrations();
|
||||||
this.props.actions.getAppliedSchemaMigrations().then((result) => {
|
}, []);
|
||||||
this.setState({
|
|
||||||
migrations: result.data,
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
render() {
|
|
||||||
const items = this.state.migrations.map((migration) => {
|
|
||||||
return (
|
|
||||||
<tr
|
|
||||||
key={migration.version}
|
|
||||||
>
|
|
||||||
<td className='whitespace--nowrap'>{migration.version}</td>
|
|
||||||
<td className='whitespace--nowrap'>{migration.name}</td>
|
|
||||||
</tr>
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
|
const items = useMemo(() => migrations.map((migration) => {
|
||||||
return (
|
return (
|
||||||
<div className={classNames('MigrationsTable', 'migrations-table__panel', this.props.className)}>
|
<tr
|
||||||
<div className='help-text'>
|
key={migration.version}
|
||||||
{this.props.createHelpText}
|
>
|
||||||
</div>
|
<td className='whitespace--nowrap'>{migration.version}</td>
|
||||||
<div className='migrations-table__table'>
|
<td className='whitespace--nowrap'>{migration.name}</td>
|
||||||
<table
|
</tr>
|
||||||
className='table'
|
|
||||||
data-testid='migrationsTable'
|
|
||||||
>
|
|
||||||
<thead>
|
|
||||||
<tr>
|
|
||||||
<th>
|
|
||||||
<FormattedMessage
|
|
||||||
id='admin.database.migrations_table.version'
|
|
||||||
defaultMessage='Version'
|
|
||||||
/>
|
|
||||||
</th>
|
|
||||||
<th>
|
|
||||||
<FormattedMessage
|
|
||||||
id='admin.database.migrations_table.name'
|
|
||||||
defaultMessage='Name'
|
|
||||||
/>
|
|
||||||
</th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody>
|
|
||||||
{items}
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
);
|
);
|
||||||
}
|
}), [migrations]);
|
||||||
}
|
|
||||||
|
|
||||||
export default MigrationsTable;
|
return (
|
||||||
|
<div className={classNames('MigrationsTable', 'migrations-table__panel', className)}>
|
||||||
|
<div className='help-text'>
|
||||||
|
{createHelpText}
|
||||||
|
</div>
|
||||||
|
<div className='migrations-table__table'>
|
||||||
|
<table
|
||||||
|
className='table'
|
||||||
|
data-testid='migrationsTable'
|
||||||
|
>
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>
|
||||||
|
<FormattedMessage
|
||||||
|
id='admin.database.migrations_table.version'
|
||||||
|
defaultMessage='Version'
|
||||||
|
/>
|
||||||
|
</th>
|
||||||
|
<th>
|
||||||
|
<FormattedMessage
|
||||||
|
id='admin.database.migrations_table.name'
|
||||||
|
defaultMessage='Name'
|
||||||
|
/>
|
||||||
|
</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{items}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default React.memo(MigrationsTable);
|
||||||
|
|||||||
Ссылка в новой задаче
Block a user