parent
5975be3690
commit
2fc32189d8
@ -1,40 +0,0 @@
|
||||
import PropTypes from 'prop-types';
|
||||
import React, { Component } from 'react';
|
||||
import TableRowCell from 'Components/Table/Cells/TableRowCell';
|
||||
import TableRow from 'Components/Table/TableRow';
|
||||
import titleCase from 'Utilities/String/titleCase';
|
||||
|
||||
class MovieTitlesRow extends Component {
|
||||
|
||||
//
|
||||
// Render
|
||||
|
||||
render() {
|
||||
const {
|
||||
title,
|
||||
sourceType
|
||||
} = this.props;
|
||||
|
||||
return (
|
||||
<TableRow>
|
||||
|
||||
<TableRowCell>
|
||||
{title}
|
||||
</TableRowCell>
|
||||
|
||||
<TableRowCell>
|
||||
{titleCase(sourceType)}
|
||||
</TableRowCell>
|
||||
|
||||
</TableRow>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
MovieTitlesRow.propTypes = {
|
||||
id: PropTypes.number.isRequired,
|
||||
title: PropTypes.string.isRequired,
|
||||
sourceType: PropTypes.string.isRequired
|
||||
};
|
||||
|
||||
export default MovieTitlesRow;
|
@ -0,0 +1,21 @@
|
||||
import React from 'react';
|
||||
import TableRowCell from 'Components/Table/Cells/TableRowCell';
|
||||
import TableRow from 'Components/Table/TableRow';
|
||||
import titleCase from 'Utilities/String/titleCase';
|
||||
|
||||
interface MovieTitlesRowProps {
|
||||
title: string;
|
||||
sourceType: string;
|
||||
}
|
||||
|
||||
function MovieTitlesRow({ title, sourceType }: MovieTitlesRowProps) {
|
||||
return (
|
||||
<TableRow>
|
||||
<TableRowCell>{title}</TableRowCell>
|
||||
|
||||
<TableRowCell>{titleCase(sourceType)}</TableRowCell>
|
||||
</TableRow>
|
||||
);
|
||||
}
|
||||
|
||||
export default MovieTitlesRow;
|
@ -1,22 +0,0 @@
|
||||
import React from 'react';
|
||||
import MovieTitlesTableContentConnector from './MovieTitlesTableContentConnector';
|
||||
import styles from './MovieTitlesTable.css';
|
||||
|
||||
function MovieTitlesTable(props) {
|
||||
const {
|
||||
...otherProps
|
||||
} = props;
|
||||
|
||||
return (
|
||||
<div className={styles.container}>
|
||||
<MovieTitlesTableContentConnector
|
||||
{...otherProps}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
MovieTitlesTable.propTypes = {
|
||||
};
|
||||
|
||||
export default MovieTitlesTable;
|
@ -0,0 +1,94 @@
|
||||
import React from 'react';
|
||||
import { useSelector } from 'react-redux';
|
||||
import { createSelector } from 'reselect';
|
||||
import AppState from 'App/State/AppState';
|
||||
import Alert from 'Components/Alert';
|
||||
import LoadingIndicator from 'Components/Loading/LoadingIndicator';
|
||||
import Column from 'Components/Table/Column';
|
||||
import Table from 'Components/Table/Table';
|
||||
import TableBody from 'Components/Table/TableBody';
|
||||
import { kinds } from 'Helpers/Props';
|
||||
import sortByProp from 'Utilities/Array/sortByProp';
|
||||
import translate from 'Utilities/String/translate';
|
||||
import MovieTitlesRow from './MovieTitlesRow';
|
||||
import styles from './MovieTitlesTable.css';
|
||||
|
||||
const columns: Column[] = [
|
||||
{
|
||||
name: 'alternativeTitle',
|
||||
label: () => translate('AlternativeTitle'),
|
||||
isVisible: true,
|
||||
},
|
||||
{
|
||||
name: 'sourceType',
|
||||
label: () => translate('Type'),
|
||||
isVisible: true,
|
||||
},
|
||||
];
|
||||
|
||||
function movieAlternativeTitlesSelector(movieId: number) {
|
||||
return createSelector(
|
||||
(state: AppState) => state.movies,
|
||||
(movies) => {
|
||||
const { isFetching, isPopulated, error, items } = movies;
|
||||
|
||||
const alternateTitles =
|
||||
items.find((m) => m.id === movieId)?.alternateTitles ?? [];
|
||||
|
||||
return {
|
||||
isFetching,
|
||||
isPopulated,
|
||||
error,
|
||||
items: alternateTitles,
|
||||
};
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
interface MovieTitlesProps {
|
||||
movieId: number;
|
||||
}
|
||||
|
||||
function MovieTitlesTable({ movieId }: MovieTitlesProps) {
|
||||
const { isFetching, isPopulated, error, items } = useSelector(
|
||||
movieAlternativeTitlesSelector(movieId)
|
||||
);
|
||||
|
||||
const sortedItems = items.sort(sortByProp('title'));
|
||||
|
||||
if (!isFetching && !!error) {
|
||||
return (
|
||||
<Alert kind={kinds.DANGER}>
|
||||
{translate('AlternativeTitlesLoadError')}
|
||||
</Alert>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<div className={styles.container}>
|
||||
{isFetching && <LoadingIndicator />}
|
||||
|
||||
{isPopulated && !items.length && !error ? (
|
||||
<div className={styles.blankpad}>
|
||||
{translate('NoAlternativeTitles')}
|
||||
</div>
|
||||
) : null}
|
||||
|
||||
{isPopulated && !!items.length && !error ? (
|
||||
<Table columns={columns}>
|
||||
<TableBody>
|
||||
{sortedItems.map((item) => (
|
||||
<MovieTitlesRow
|
||||
key={item.id}
|
||||
title={item.title}
|
||||
sourceType={item.sourceType}
|
||||
/>
|
||||
))}
|
||||
</TableBody>
|
||||
</Table>
|
||||
) : null}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default MovieTitlesTable;
|
@ -1,5 +0,0 @@
|
||||
.blankpad {
|
||||
padding-top: 10px;
|
||||
padding-bottom: 10px;
|
||||
padding-left: 2em;
|
||||
}
|
@ -1,7 +0,0 @@
|
||||
// This file is automatically generated.
|
||||
// Please do not change this file!
|
||||
interface CssExports {
|
||||
'blankpad': string;
|
||||
}
|
||||
export const cssExports: CssExports;
|
||||
export default cssExports;
|
@ -1,87 +0,0 @@
|
||||
import PropTypes from 'prop-types';
|
||||
import React, { Component } from 'react';
|
||||
import LoadingIndicator from 'Components/Loading/LoadingIndicator';
|
||||
import Table from 'Components/Table/Table';
|
||||
import TableBody from 'Components/Table/TableBody';
|
||||
import translate from 'Utilities/String/translate';
|
||||
import MovieTitlesRow from './MovieTitlesRow';
|
||||
import styles from './MovieTitlesTableContent.css';
|
||||
|
||||
const columns = [
|
||||
{
|
||||
name: 'altTitle',
|
||||
label: () => translate('AlternativeTitle'),
|
||||
isVisible: true
|
||||
},
|
||||
{
|
||||
name: 'sourceType',
|
||||
label: () => translate('Type'),
|
||||
isVisible: true
|
||||
}
|
||||
];
|
||||
|
||||
class MovieTitlesTableContent extends Component {
|
||||
|
||||
//
|
||||
// Render
|
||||
|
||||
render() {
|
||||
const {
|
||||
isFetching,
|
||||
isPopulated,
|
||||
error,
|
||||
items
|
||||
} = this.props;
|
||||
|
||||
const hasItems = !!items.length;
|
||||
return (
|
||||
<div>
|
||||
{
|
||||
isFetching &&
|
||||
<LoadingIndicator />
|
||||
}
|
||||
|
||||
{
|
||||
!isFetching && !!error &&
|
||||
<div className={styles.blankpad}>
|
||||
{translate('UnableToLoadAltTitle')}
|
||||
</div>
|
||||
}
|
||||
|
||||
{
|
||||
isPopulated && !hasItems && !error &&
|
||||
<div className={styles.blankpad}>
|
||||
{translate('NoAltTitle')}
|
||||
</div>
|
||||
}
|
||||
|
||||
{
|
||||
isPopulated && hasItems && !error &&
|
||||
<Table columns={columns}>
|
||||
<TableBody>
|
||||
{
|
||||
items.reverse().map((item) => {
|
||||
return (
|
||||
<MovieTitlesRow
|
||||
key={item.id}
|
||||
{...item}
|
||||
/>
|
||||
);
|
||||
})
|
||||
}
|
||||
</TableBody>
|
||||
</Table>
|
||||
}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
MovieTitlesTableContent.propTypes = {
|
||||
isFetching: PropTypes.bool.isRequired,
|
||||
isPopulated: PropTypes.bool.isRequired,
|
||||
error: PropTypes.object,
|
||||
items: PropTypes.arrayOf(PropTypes.object).isRequired
|
||||
};
|
||||
|
||||
export default MovieTitlesTableContent;
|
@ -1,60 +0,0 @@
|
||||
import PropTypes from 'prop-types';
|
||||
import React, { Component } from 'react';
|
||||
import { connect } from 'react-redux';
|
||||
import { createSelector } from 'reselect';
|
||||
import MovieTitlesTableContent from './MovieTitlesTableContent';
|
||||
|
||||
function createMapStateToProps() {
|
||||
return createSelector(
|
||||
(state, { movieId }) => movieId,
|
||||
(state) => state.movies,
|
||||
(movieId, movies) => {
|
||||
const {
|
||||
isFetching,
|
||||
isPopulated,
|
||||
error,
|
||||
items
|
||||
} = movies;
|
||||
|
||||
const alternateTitles = items.find((m) => m.id === movieId)?.alternateTitles;
|
||||
|
||||
return {
|
||||
isFetching,
|
||||
isPopulated,
|
||||
error,
|
||||
alternateTitles
|
||||
};
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
class MovieTitlesTableContentConnector extends Component {
|
||||
|
||||
//
|
||||
// Render
|
||||
|
||||
render() {
|
||||
const {
|
||||
alternateTitles,
|
||||
...otherProps
|
||||
} = this.props;
|
||||
|
||||
return (
|
||||
<MovieTitlesTableContent
|
||||
{...otherProps}
|
||||
items={alternateTitles}
|
||||
/>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
MovieTitlesTableContentConnector.propTypes = {
|
||||
movieId: PropTypes.number.isRequired,
|
||||
alternateTitles: PropTypes.arrayOf(PropTypes.object).isRequired
|
||||
};
|
||||
|
||||
MovieTitlesTableContentConnector.defaultProps = {
|
||||
alternateTitles: []
|
||||
};
|
||||
|
||||
export default connect(createMapStateToProps)(MovieTitlesTableContentConnector);
|
Loading…
Reference in new issue