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