diff --git a/ui/src/album/AlbumListView.js b/ui/src/album/AlbumListView.js index ca0621542..e5cdd99bd 100644 --- a/ui/src/album/AlbumListView.js +++ b/ui/src/album/AlbumListView.js @@ -21,6 +21,7 @@ import { } from '../common' import { AlbumContextMenu } from '../common' import { makeStyles } from '@material-ui/core/styles' +import MultiLineTextField from '../common/MultiLineTextField' const useStyles = makeStyles({ columnIcon: { @@ -39,6 +40,7 @@ const AlbumDetails = (props) => { + ) diff --git a/ui/src/common/MultiLineTextField.js b/ui/src/common/MultiLineTextField.js new file mode 100644 index 000000000..2f267925f --- /dev/null +++ b/ui/src/common/MultiLineTextField.js @@ -0,0 +1,37 @@ +import React, { memo } from 'react' +import get from 'lodash.get' +import Typography from '@material-ui/core/Typography' +import sanitizeFieldRestProps from './sanitizeFieldRestProps' +import md5 from 'md5-hex' + +const MultiLineTextField = memo( + ({ className, emptyText, source, record = {}, stripTags, ...rest }) => { + const value = get(record, source) + const lines = value ? value.split('\n') : [] + + return ( + + {lines.length === 0 && emptyText + ? emptyText + : lines.map((line, idx) => ( +
+ ))} + + ) + } +) + +MultiLineTextField.defaultProps = { + addLabel: true, +} + +export default MultiLineTextField diff --git a/ui/src/common/MultiLineTextField.test.js b/ui/src/common/MultiLineTextField.test.js new file mode 100644 index 000000000..bc26d5cb7 --- /dev/null +++ b/ui/src/common/MultiLineTextField.test.js @@ -0,0 +1,30 @@ +import * as React from 'react' +import { render, cleanup, screen } from '@testing-library/react' +import MultiLineTextField from './MultiLineTextField' + +describe('', () => { + afterEach(cleanup) + + it('should render each line in a separated div', () => { + const record = { comment: 'line1\nline2' } + const { queryByTestId } = render( + + ) + expect(queryByTestId('comment.0').textContent).toBe('line1') + expect(queryByTestId('comment.1').textContent).toBe('line2') + }) + + it.each([null, undefined])( + 'should render the emptyText when value is %s', + (body) => { + const { queryByText } = render( + + ) + expect(queryByText('NA')).not.toBeNull() + } + ) +}) diff --git a/ui/src/common/SongDetails.js b/ui/src/common/SongDetails.js index fe4c39cc2..fd0b624f4 100644 --- a/ui/src/common/SongDetails.js +++ b/ui/src/common/SongDetails.js @@ -8,6 +8,7 @@ import TableRow from '@material-ui/core/TableRow' import { BooleanField, DateField, TextField, useTranslate } from 'react-admin' import inflection from 'inflection' import { BitrateField, SizeField } from './index' +import MultiLineTextField from './MultiLineTextField' export const SongDetails = (props) => { const translate = useTranslate() @@ -23,6 +24,7 @@ export const SongDetails = (props) => { size: , updatedAt: , playCount: , + comment: , } if (!record.discSubtitle) { delete data.discSubtitle diff --git a/ui/src/common/sanitizeFieldRestProps.js b/ui/src/common/sanitizeFieldRestProps.js new file mode 100644 index 000000000..c3a1edf2a --- /dev/null +++ b/ui/src/common/sanitizeFieldRestProps.js @@ -0,0 +1,26 @@ +const sanitizeFieldRestProps = ({ + addLabel, + allowEmpty, + basePath, + cellClassName, + className, + emptyText, + formClassName, + fullWidth, + headerClassName, + label, + linkType, + link, + locale, + record, + resource, + sortable, + sortBy, + sortByOrder, + source, + textAlign, + translateChoice, + ...props +}) => props + +export default sanitizeFieldRestProps