mirror of
https://github.com/strapi/strapi.git
synced 2025-09-21 22:40:24 +00:00
refactor making cell dynamic with CellContent
This commit is contained in:
parent
a04305a2bb
commit
a3ae1310ca
@ -0,0 +1,72 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { useIntl } from 'react-intl';
|
||||
import { getFileExtension } from '@strapi/helper-plugin';
|
||||
import { Typography } from '@strapi/design-system/Typography';
|
||||
|
||||
import { PreviewCell } from './PreviewCell';
|
||||
import { formatBytes } from '../../utils';
|
||||
|
||||
export const CellContent = ({
|
||||
alternativeText,
|
||||
content,
|
||||
cellType,
|
||||
elementType,
|
||||
mime,
|
||||
fileExtension,
|
||||
thumbnailURL,
|
||||
url,
|
||||
}) => {
|
||||
const { formatDate } = useIntl();
|
||||
switch (cellType) {
|
||||
case 'image':
|
||||
return (
|
||||
<PreviewCell
|
||||
alternativeText={alternativeText}
|
||||
fileExtension={fileExtension}
|
||||
mime={mime}
|
||||
type={elementType}
|
||||
thumbnailURL={thumbnailURL}
|
||||
url={url}
|
||||
/>
|
||||
);
|
||||
case 'date':
|
||||
return <Typography>{formatDate(content)}</Typography>;
|
||||
|
||||
case 'size':
|
||||
if (elementType === 'folder') return <Typography>-</Typography>;
|
||||
|
||||
return <Typography>{formatBytes(content)}</Typography>;
|
||||
|
||||
case 'ext':
|
||||
if (elementType === 'folder') return <Typography>-</Typography>;
|
||||
|
||||
return <Typography>{getFileExtension(content).toUpperCase()}</Typography>;
|
||||
|
||||
case 'text':
|
||||
return <Typography>{content}</Typography>;
|
||||
|
||||
default:
|
||||
return <Typography>-</Typography>;
|
||||
}
|
||||
};
|
||||
|
||||
CellContent.defaultProps = {
|
||||
alternativeText: null,
|
||||
content: '',
|
||||
fileExtension: '',
|
||||
mime: '',
|
||||
thumbnailURL: null,
|
||||
url: null,
|
||||
};
|
||||
|
||||
CellContent.propTypes = {
|
||||
alternativeText: PropTypes.string,
|
||||
content: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),
|
||||
fileExtension: PropTypes.string,
|
||||
mime: PropTypes.string,
|
||||
thumbnailURL: PropTypes.string,
|
||||
cellType: PropTypes.string.isRequired,
|
||||
elementType: PropTypes.string.isRequired,
|
||||
url: PropTypes.string,
|
||||
};
|
@ -7,30 +7,17 @@ import { IconButton } from '@strapi/design-system/IconButton';
|
||||
import { Tbody, Td, Tr } from '@strapi/design-system/Table';
|
||||
import Pencil from '@strapi/icons/Pencil';
|
||||
|
||||
import { PreviewCell } from './PreviewCell';
|
||||
import { TextCell } from './TextCell';
|
||||
import { AssetDefinition, FolderDefinition } from '../../constants';
|
||||
import { formatBytes, getTrad } from '../../utils';
|
||||
import { CellContent } from './CellContent';
|
||||
import { AssetDefinition, FolderDefinition, tableHeaders as cells } from '../../constants';
|
||||
import { getTrad } from '../../utils';
|
||||
|
||||
export const TableRows = ({ onEditAsset, onEditFolder, onSelectOne, rows, selected }) => {
|
||||
const { formatDate, formatMessage } = useIntl();
|
||||
const { formatMessage } = useIntl();
|
||||
|
||||
return (
|
||||
<Tbody>
|
||||
{rows.map((element) => {
|
||||
const {
|
||||
alternativeText,
|
||||
id,
|
||||
name,
|
||||
ext,
|
||||
size,
|
||||
createdAt,
|
||||
updatedAt,
|
||||
url,
|
||||
mime,
|
||||
formats,
|
||||
type,
|
||||
} = element;
|
||||
const { alternativeText, id, name, ext, url, mime, formats, type: elementType } = element;
|
||||
|
||||
const isSelected = !!selected.find((currentRow) => currentRow.id === id);
|
||||
|
||||
@ -40,49 +27,43 @@ export const TableRows = ({ onEditAsset, onEditFolder, onSelectOne, rows, select
|
||||
<BaseCheckbox
|
||||
aria-label={formatMessage(
|
||||
{
|
||||
id: type === 'asset' ? 'list-assets-select' : 'list.folder.select',
|
||||
id: elementType === 'asset' ? 'list-assets-select' : 'list.folder.select',
|
||||
defaultMessage:
|
||||
type === 'asset' ? 'Select {name} asset' : 'Select {name} folder',
|
||||
elementType === 'asset' ? 'Select {name} asset' : 'Select {name} folder',
|
||||
},
|
||||
{ name }
|
||||
)}
|
||||
onValueChange={() => onSelectOne({ ...element, type })}
|
||||
onValueChange={() => onSelectOne({ ...element, elementType })}
|
||||
checked={isSelected}
|
||||
/>
|
||||
</Td>
|
||||
<Td>
|
||||
<PreviewCell
|
||||
alternativeText={alternativeText}
|
||||
fileExtension={getFileExtension(ext)}
|
||||
mime={mime}
|
||||
type={type}
|
||||
thumbnailURL={formats?.thumbnail?.url}
|
||||
url={url}
|
||||
/>
|
||||
</Td>
|
||||
<Td>
|
||||
<TextCell content={name} />
|
||||
</Td>
|
||||
<Td>
|
||||
<TextCell content={ext && getFileExtension(ext).toUpperCase()} />
|
||||
</Td>
|
||||
<Td>
|
||||
<TextCell content={size && formatBytes(size)} />
|
||||
</Td>
|
||||
<Td>
|
||||
<TextCell content={formatDate(new Date(createdAt))} />
|
||||
</Td>
|
||||
<Td>
|
||||
<TextCell content={formatDate(new Date(updatedAt))} />
|
||||
</Td>
|
||||
{((type === 'asset' && onEditAsset) || (type === 'folder' && onEditFolder)) && (
|
||||
{cells.map(({ name, type: cellType }) => {
|
||||
return (
|
||||
<Td key={name}>
|
||||
<CellContent
|
||||
alternativeText={alternativeText}
|
||||
content={element[name]}
|
||||
fileExtension={getFileExtension(ext)}
|
||||
mime={mime}
|
||||
cellType={cellType}
|
||||
elementType={elementType}
|
||||
thumbnailURL={formats?.thumbnail?.url}
|
||||
url={url}
|
||||
/>
|
||||
</Td>
|
||||
);
|
||||
})}
|
||||
{((elementType === 'asset' && onEditAsset) ||
|
||||
(elementType === 'folder' && onEditFolder)) && (
|
||||
<Td>
|
||||
<IconButton
|
||||
label={formatMessage({
|
||||
id: getTrad('control-card.edit'),
|
||||
defaultMessage: 'Edit',
|
||||
})}
|
||||
onClick={() => (type === 'asset' ? onEditAsset(element) : onEditFolder(element))}
|
||||
onClick={() =>
|
||||
elementType === 'asset' ? onEditAsset(element) : onEditFolder(element)
|
||||
}
|
||||
noBorder
|
||||
>
|
||||
<Pencil />
|
||||
|
@ -1,19 +0,0 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { Typography } from '@strapi/design-system/Typography';
|
||||
|
||||
export const TextCell = ({ content }) => {
|
||||
if (content) {
|
||||
return <Typography>{content}</Typography>;
|
||||
}
|
||||
|
||||
return <Typography>-</Typography>;
|
||||
};
|
||||
|
||||
TextCell.defaultProps = {
|
||||
content: '',
|
||||
};
|
||||
|
||||
TextCell.propTypes = {
|
||||
content: PropTypes.string,
|
||||
};
|
@ -0,0 +1,78 @@
|
||||
import React from 'react';
|
||||
import { IntlProvider } from 'react-intl';
|
||||
import { render } from '@testing-library/react';
|
||||
import { ThemeProvider, lightTheme } from '@strapi/design-system';
|
||||
|
||||
import { CellContent } from '../CellContent';
|
||||
|
||||
const PROPS_FIXTURE = {
|
||||
alternativeText: 'alternative alt',
|
||||
cellType: 'image',
|
||||
elementType: 'asset',
|
||||
content: 'michka-picture-url-default.jpeg',
|
||||
fileExtension: '.jpeg',
|
||||
mime: 'image/jpeg',
|
||||
thumbnailURL: 'michka-picture-url-thumbnail.jpeg',
|
||||
url: 'michka-picture-url-default.jpeg',
|
||||
};
|
||||
|
||||
const ComponentFixture = (props) => {
|
||||
const customProps = {
|
||||
...PROPS_FIXTURE,
|
||||
...props,
|
||||
};
|
||||
|
||||
return (
|
||||
<IntlProvider locale="en" messages={{}}>
|
||||
<ThemeProvider theme={lightTheme}>
|
||||
<CellContent {...PROPS_FIXTURE} {...customProps} />
|
||||
</ThemeProvider>
|
||||
</IntlProvider>
|
||||
);
|
||||
};
|
||||
|
||||
const setup = (props) => render(<ComponentFixture {...props} />);
|
||||
|
||||
describe('TableList | CellContent', () => {
|
||||
it('should render image cell type when element type is asset and mime includes image', () => {
|
||||
const { getByRole } = setup();
|
||||
|
||||
expect(getByRole('img', { name: 'alternative alt' })).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('should render image cell type when element type is asset and mime does not include image', () => {
|
||||
const { getByText } = setup({ mime: 'application/pdf', fileExtension: 'pdf' });
|
||||
|
||||
expect(getByText('pdf')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('should render image cell type when element type is folder', () => {
|
||||
const { container } = setup({ elementType: 'folder' });
|
||||
|
||||
expect(container.querySelector('path')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('should render text cell type', () => {
|
||||
const { getByText } = setup({ cellType: 'text', content: 'some text' });
|
||||
|
||||
expect(getByText('some text')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('should render extension cell type', () => {
|
||||
const { getByText } = setup({ cellType: 'ext', content: '.pdf' });
|
||||
|
||||
expect(getByText('PDF')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('should render size cell type', () => {
|
||||
const { getByText } = setup({ cellType: 'size', content: '20.5435' });
|
||||
|
||||
expect(getByText('21KB')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('should render date cell type', () => {
|
||||
const { getByText } = setup({ cellType: 'date', content: '2022-11-18T12:08:02.202Z' });
|
||||
|
||||
expect(getByText('11/18/2022')).toBeInTheDocument();
|
||||
});
|
||||
});
|
@ -1,27 +0,0 @@
|
||||
import React from 'react';
|
||||
import { render } from '@testing-library/react';
|
||||
import { ThemeProvider, lightTheme } from '@strapi/design-system';
|
||||
|
||||
import { TextCell } from '../TextCell';
|
||||
|
||||
const ComponentFixture = (props) => (
|
||||
<ThemeProvider theme={lightTheme}>
|
||||
<TextCell {...props} />
|
||||
</ThemeProvider>
|
||||
);
|
||||
|
||||
const setup = (props) => render(<ComponentFixture {...props} />);
|
||||
|
||||
describe('TableList | TextCell', () => {
|
||||
it('should render content', () => {
|
||||
const { getByText } = setup({ content: 'michka' });
|
||||
|
||||
expect(getByText('michka')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('should render a default content', () => {
|
||||
const { getByText } = setup();
|
||||
|
||||
expect(getByText('-')).toBeInTheDocument();
|
||||
});
|
||||
});
|
@ -105,6 +105,7 @@ export const tableHeaders = [
|
||||
label: { id: getTrad('list-table-header-preview'), defaultMessage: 'preview' },
|
||||
sortable: false,
|
||||
},
|
||||
type: 'image',
|
||||
},
|
||||
{
|
||||
name: 'name',
|
||||
@ -113,6 +114,7 @@ export const tableHeaders = [
|
||||
label: { id: getTrad('list-table-header-name'), defaultMessage: 'name' },
|
||||
sortable: true,
|
||||
},
|
||||
type: 'text',
|
||||
},
|
||||
{
|
||||
name: 'ext',
|
||||
@ -121,6 +123,7 @@ export const tableHeaders = [
|
||||
label: { id: getTrad('list-table-header-ext'), defaultMessage: 'extension' },
|
||||
sortable: false,
|
||||
},
|
||||
type: 'ext',
|
||||
},
|
||||
{
|
||||
name: 'size',
|
||||
@ -129,6 +132,7 @@ export const tableHeaders = [
|
||||
label: { id: getTrad('list-table-header-size'), defaultMessage: 'size' },
|
||||
sortable: false,
|
||||
},
|
||||
type: 'size',
|
||||
},
|
||||
{
|
||||
name: 'createdAt',
|
||||
@ -137,6 +141,7 @@ export const tableHeaders = [
|
||||
label: { id: getTrad('list-table-header-createdAt'), defaultMessage: 'created' },
|
||||
sortable: true,
|
||||
},
|
||||
type: 'date',
|
||||
},
|
||||
{
|
||||
name: 'updatedAt',
|
||||
@ -145,6 +150,7 @@ export const tableHeaders = [
|
||||
label: { id: getTrad('list-table-header-updatedAt'), defaultMessage: 'last update' },
|
||||
sortable: true,
|
||||
},
|
||||
type: 'date',
|
||||
},
|
||||
];
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user