mirror of
https://github.com/navidrome/navidrome.git
synced 2025-04-03 20:47:35 +03:00
fix: restore old date display/sort behaviour (#3862)
* fix(server): bring back legacy date mappings Signed-off-by: Deluan <deluan@navidrome.org> * reuse the mapDates logic in the legacyReleaseDate function Signed-off-by: Deluan <deluan@navidrome.org> * fix mappings Signed-off-by: Deluan <deluan@navidrome.org> * show original and release dates in album grid Signed-off-by: Deluan <deluan@navidrome.org> * fix tests based on new year mapping Signed-off-by: Deluan <deluan@navidrome.org> * fix(subsonic): prefer returning original_year over (recording) year when sorting albums Signed-off-by: Deluan <deluan@navidrome.org> * fix case when we don't have originalYear Signed-off-by: Deluan <deluan@navidrome.org> * show all dates in album's info, and remove the recording date from the album page Signed-off-by: Deluan <deluan@navidrome.org> * better? Signed-off-by: Deluan <deluan@navidrome.org> * add snapshot tests for Album Details Signed-off-by: Deluan <deluan@navidrome.org> * fix(subsonic): sort order for getAlbumList?type=byYear Signed-off-by: Deluan <deluan@navidrome.org> --------- Signed-off-by: Deluan <deluan@navidrome.org>
This commit is contained in:
parent
88f87e6c4f
commit
2b84c574ba
20 changed files with 929 additions and 155 deletions
19
ui/src/album/AlbumDatesField.jsx
Normal file
19
ui/src/album/AlbumDatesField.jsx
Normal file
|
@ -0,0 +1,19 @@
|
|||
import { useRecordContext } from 'react-admin'
|
||||
import { formatRange } from '../common/index.js'
|
||||
|
||||
const originalYearSymbol = '♫'
|
||||
const releaseYearSymbol = '○'
|
||||
|
||||
export const AlbumDatesField = ({ className, ...rest }) => {
|
||||
const record = useRecordContext(rest)
|
||||
const releaseDate = record.releaseDate
|
||||
const releaseYear = releaseDate?.toString().substring(0, 4)
|
||||
const yearRange =
|
||||
formatRange(record, 'originalYear') || record['maxYear']?.toString()
|
||||
let label = yearRange
|
||||
|
||||
if (releaseYear !== undefined && yearRange !== releaseYear) {
|
||||
label = `${originalYearSymbol} ${yearRange} · ${releaseYearSymbol} ${releaseYear}`
|
||||
}
|
||||
return <span className={className}>{label}</span>
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
import { useState, useEffect, useCallback } from 'react'
|
||||
import { useCallback, useEffect, useState } from 'react'
|
||||
import {
|
||||
Card,
|
||||
CardContent,
|
||||
|
@ -10,25 +10,25 @@ import {
|
|||
withWidth,
|
||||
} from '@material-ui/core'
|
||||
import {
|
||||
useRecordContext,
|
||||
useTranslate,
|
||||
ArrayField,
|
||||
SingleFieldList,
|
||||
ChipField,
|
||||
Link,
|
||||
SingleFieldList,
|
||||
useRecordContext,
|
||||
useTranslate,
|
||||
} from 'react-admin'
|
||||
import Lightbox from 'react-image-lightbox'
|
||||
import 'react-image-lightbox/style.css'
|
||||
import subsonic from '../subsonic'
|
||||
import {
|
||||
ArtistLinkField,
|
||||
CollapsibleComment,
|
||||
DurationField,
|
||||
formatRange,
|
||||
SizeField,
|
||||
LoveButton,
|
||||
RatingField,
|
||||
SizeField,
|
||||
useAlbumsPerPage,
|
||||
CollapsibleComment,
|
||||
} from '../common'
|
||||
import config from '../config'
|
||||
import { formatFullDate, intersperse } from '../utils'
|
||||
|
@ -140,69 +140,55 @@ const GenreList = () => {
|
|||
)
|
||||
}
|
||||
|
||||
const Details = (props) => {
|
||||
export const Details = (props) => {
|
||||
const isXsmall = useMediaQuery((theme) => theme.breakpoints.down('xs'))
|
||||
const translate = useTranslate()
|
||||
const record = useRecordContext(props)
|
||||
|
||||
// Create an array of detail elements
|
||||
let details = []
|
||||
const addDetail = (obj) => {
|
||||
const id = details.length
|
||||
details.push(<span key={`detail-${record.id}-${id}`}>{obj}</span>)
|
||||
}
|
||||
|
||||
const originalYearRange = formatRange(record, 'originalYear')
|
||||
const originalDate = record.originalDate
|
||||
? formatFullDate(record.originalDate)
|
||||
: originalYearRange
|
||||
// Calculate date related fields
|
||||
const yearRange = formatRange(record, 'year')
|
||||
const date = record.date ? formatFullDate(record.date) : yearRange
|
||||
const releaseDate = record.releaseDate
|
||||
? formatFullDate(record.releaseDate)
|
||||
: date
|
||||
|
||||
const showReleaseDate = date !== releaseDate && releaseDate.length > 3
|
||||
const showOriginalDate =
|
||||
date !== originalDate &&
|
||||
originalDate !== releaseDate &&
|
||||
originalDate.length > 3
|
||||
const originalDate = record.originalDate
|
||||
? formatFullDate(record.originalDate)
|
||||
: formatRange(record, 'originalYear')
|
||||
const releaseDate = record?.releaseDate && formatFullDate(record.releaseDate)
|
||||
|
||||
showOriginalDate &&
|
||||
!isXsmall &&
|
||||
const dateToUse = originalDate || date
|
||||
const isOriginalDate = originalDate && dateToUse !== date
|
||||
const showDate = dateToUse && dateToUse !== releaseDate
|
||||
|
||||
// Get label for the main date display
|
||||
const getDateLabel = () => {
|
||||
if (isXsmall) return '♫'
|
||||
if (isOriginalDate) return translate('resources.album.fields.originalDate')
|
||||
return null
|
||||
}
|
||||
|
||||
// Get label for release date display
|
||||
const getReleaseDateLabel = () => {
|
||||
if (!isXsmall) return translate('resources.album.fields.releaseDate')
|
||||
if (showDate) return '○'
|
||||
return null
|
||||
}
|
||||
|
||||
// Display dates with appropriate labels
|
||||
if (showDate) {
|
||||
addDetail(<>{[getDateLabel(), dateToUse].filter(Boolean).join(' ')}</>)
|
||||
}
|
||||
|
||||
if (releaseDate) {
|
||||
addDetail(
|
||||
<>
|
||||
{[translate('resources.album.fields.originalDate'), originalDate].join(
|
||||
' ',
|
||||
)}
|
||||
</>,
|
||||
<>{[getReleaseDateLabel(), releaseDate].filter(Boolean).join(' ')}</>,
|
||||
)
|
||||
|
||||
yearRange && addDetail(<>{['♫', !isXsmall ? date : yearRange].join(' ')}</>)
|
||||
|
||||
showReleaseDate &&
|
||||
addDetail(
|
||||
<>
|
||||
{(!isXsmall
|
||||
? [translate('resources.album.fields.releaseDate'), releaseDate]
|
||||
: ['○', record.releaseDate.substring(0, 4)]
|
||||
).join(' ')}
|
||||
</>,
|
||||
)
|
||||
|
||||
const showReleases = record.releases > 1
|
||||
showReleases &&
|
||||
addDetail(
|
||||
<>
|
||||
{!isXsmall
|
||||
? [
|
||||
record.releases,
|
||||
translate('resources.album.fields.releases', {
|
||||
smart_count: record.releases,
|
||||
}),
|
||||
].join(' ')
|
||||
: ['(', record.releases, ')))'].join(' ')}
|
||||
</>,
|
||||
)
|
||||
|
||||
}
|
||||
addDetail(
|
||||
<>
|
||||
{record.songCount +
|
||||
|
@ -215,6 +201,7 @@ const Details = (props) => {
|
|||
!isXsmall && addDetail(<DurationField source={'duration'} />)
|
||||
!isXsmall && addDetail(<SizeField source="size" />)
|
||||
|
||||
// Return the details rendered with separators
|
||||
return <>{intersperse(details, ' · ')}</>
|
||||
}
|
||||
|
||||
|
|
327
ui/src/album/AlbumDetails.test.jsx
Normal file
327
ui/src/album/AlbumDetails.test.jsx
Normal file
|
@ -0,0 +1,327 @@
|
|||
// ui/src/album/__tests__/AlbumDetails.test.jsx
|
||||
import { describe, test, expect, beforeEach, afterEach } from 'vitest'
|
||||
import { render } from '@testing-library/react'
|
||||
import { RecordContextProvider } from 'react-admin'
|
||||
import { useMediaQuery } from '@material-ui/core'
|
||||
import { Details } from './AlbumDetails'
|
||||
|
||||
// Mock useMediaQuery
|
||||
vi.mock('@material-ui/core', async () => {
|
||||
const actual = await import('@material-ui/core')
|
||||
return {
|
||||
...actual,
|
||||
useMediaQuery: vi.fn(),
|
||||
}
|
||||
})
|
||||
|
||||
describe('Details component', () => {
|
||||
describe('Desktop view', () => {
|
||||
beforeEach(() => {
|
||||
// Set desktop view (isXsmall = false)
|
||||
vi.mocked(useMediaQuery).mockReturnValue(false)
|
||||
})
|
||||
|
||||
test('renders correctly with just year range', () => {
|
||||
const record = {
|
||||
id: '123',
|
||||
name: 'Test Album',
|
||||
songCount: 12,
|
||||
duration: 3600,
|
||||
size: 102400,
|
||||
year: 2020,
|
||||
}
|
||||
|
||||
const { container } = render(
|
||||
<RecordContextProvider value={record}>
|
||||
<Details />
|
||||
</RecordContextProvider>,
|
||||
)
|
||||
|
||||
expect(container).toMatchSnapshot()
|
||||
})
|
||||
|
||||
test('renders correctly with date', () => {
|
||||
const record = {
|
||||
id: '123',
|
||||
name: 'Test Album',
|
||||
songCount: 12,
|
||||
duration: 3600,
|
||||
size: 102400,
|
||||
date: '2020-05-01',
|
||||
}
|
||||
|
||||
const { container } = render(
|
||||
<RecordContextProvider value={record}>
|
||||
<Details />
|
||||
</RecordContextProvider>,
|
||||
)
|
||||
|
||||
expect(container).toMatchSnapshot()
|
||||
})
|
||||
|
||||
test('renders correctly with originalDate', () => {
|
||||
const record = {
|
||||
id: '123',
|
||||
name: 'Test Album',
|
||||
songCount: 12,
|
||||
duration: 3600,
|
||||
size: 102400,
|
||||
originalDate: '2018-03-15',
|
||||
}
|
||||
|
||||
const { container } = render(
|
||||
<RecordContextProvider value={record}>
|
||||
<Details />
|
||||
</RecordContextProvider>,
|
||||
)
|
||||
|
||||
expect(container).toMatchSnapshot()
|
||||
})
|
||||
|
||||
test('renders correctly with date and originalDate', () => {
|
||||
const record = {
|
||||
id: '123',
|
||||
name: 'Test Album',
|
||||
songCount: 12,
|
||||
duration: 3600,
|
||||
size: 102400,
|
||||
date: '2020-05-01',
|
||||
originalDate: '2018-03-15',
|
||||
}
|
||||
|
||||
const { container } = render(
|
||||
<RecordContextProvider value={record}>
|
||||
<Details />
|
||||
</RecordContextProvider>,
|
||||
)
|
||||
|
||||
expect(container).toMatchSnapshot()
|
||||
})
|
||||
|
||||
test('renders correctly with releaseDate', () => {
|
||||
const record = {
|
||||
id: '123',
|
||||
name: 'Test Album',
|
||||
songCount: 12,
|
||||
duration: 3600,
|
||||
size: 102400,
|
||||
releaseDate: '2020-06-15',
|
||||
}
|
||||
|
||||
const { container } = render(
|
||||
<RecordContextProvider value={record}>
|
||||
<Details />
|
||||
</RecordContextProvider>,
|
||||
)
|
||||
|
||||
expect(container).toMatchSnapshot()
|
||||
})
|
||||
|
||||
test('renders correctly with all date fields', () => {
|
||||
const record = {
|
||||
id: '123',
|
||||
name: 'Test Album',
|
||||
songCount: 12,
|
||||
duration: 3600,
|
||||
size: 102400,
|
||||
date: '2020-05-01',
|
||||
originalDate: '2018-03-15',
|
||||
releaseDate: '2020-06-15',
|
||||
}
|
||||
|
||||
const { container } = render(
|
||||
<RecordContextProvider value={record}>
|
||||
<Details />
|
||||
</RecordContextProvider>,
|
||||
)
|
||||
|
||||
expect(container).toMatchSnapshot()
|
||||
})
|
||||
})
|
||||
|
||||
describe('Mobile view', () => {
|
||||
beforeEach(() => {
|
||||
// Set mobile view (isXsmall = true)
|
||||
vi.mocked(useMediaQuery).mockReturnValue(true)
|
||||
})
|
||||
|
||||
afterEach(() => {
|
||||
vi.clearAllMocks()
|
||||
})
|
||||
|
||||
test('renders correctly with just year range', () => {
|
||||
const record = {
|
||||
id: '123',
|
||||
name: 'Test Album',
|
||||
songCount: 12,
|
||||
duration: 3600,
|
||||
size: 102400,
|
||||
year: 2020,
|
||||
}
|
||||
|
||||
const { container } = render(
|
||||
<RecordContextProvider value={record}>
|
||||
<Details />
|
||||
</RecordContextProvider>,
|
||||
)
|
||||
|
||||
expect(container).toMatchSnapshot()
|
||||
})
|
||||
|
||||
test('renders correctly with date', () => {
|
||||
const record = {
|
||||
id: '123',
|
||||
name: 'Test Album',
|
||||
songCount: 12,
|
||||
duration: 3600,
|
||||
size: 102400,
|
||||
date: '2020-05-01',
|
||||
}
|
||||
|
||||
const { container } = render(
|
||||
<RecordContextProvider value={record}>
|
||||
<Details />
|
||||
</RecordContextProvider>,
|
||||
)
|
||||
|
||||
expect(container).toMatchSnapshot()
|
||||
})
|
||||
|
||||
test('renders correctly with originalDate', () => {
|
||||
const record = {
|
||||
id: '123',
|
||||
name: 'Test Album',
|
||||
songCount: 12,
|
||||
duration: 3600,
|
||||
size: 102400,
|
||||
originalDate: '2018-03-15',
|
||||
}
|
||||
|
||||
const { container } = render(
|
||||
<RecordContextProvider value={record}>
|
||||
<Details />
|
||||
</RecordContextProvider>,
|
||||
)
|
||||
|
||||
expect(container).toMatchSnapshot()
|
||||
})
|
||||
|
||||
test('renders correctly with date and originalDate', () => {
|
||||
const record = {
|
||||
id: '123',
|
||||
name: 'Test Album',
|
||||
songCount: 12,
|
||||
duration: 3600,
|
||||
size: 102400,
|
||||
date: '2020-05-01',
|
||||
originalDate: '2018-03-15',
|
||||
}
|
||||
|
||||
const { container } = render(
|
||||
<RecordContextProvider value={record}>
|
||||
<Details />
|
||||
</RecordContextProvider>,
|
||||
)
|
||||
|
||||
expect(container).toMatchSnapshot()
|
||||
})
|
||||
|
||||
test('renders correctly with releaseDate', () => {
|
||||
const record = {
|
||||
id: '123',
|
||||
name: 'Test Album',
|
||||
songCount: 12,
|
||||
duration: 3600,
|
||||
size: 102400,
|
||||
releaseDate: '2020-06-15',
|
||||
}
|
||||
|
||||
const { container } = render(
|
||||
<RecordContextProvider value={record}>
|
||||
<Details />
|
||||
</RecordContextProvider>,
|
||||
)
|
||||
|
||||
expect(container).toMatchSnapshot()
|
||||
})
|
||||
|
||||
test('renders correctly with all date fields', () => {
|
||||
const record = {
|
||||
id: '123',
|
||||
name: 'Test Album',
|
||||
songCount: 12,
|
||||
duration: 3600,
|
||||
size: 102400,
|
||||
date: '2020-05-01',
|
||||
originalDate: '2018-03-15',
|
||||
releaseDate: '2020-06-15',
|
||||
}
|
||||
|
||||
const { container } = render(
|
||||
<RecordContextProvider value={record}>
|
||||
<Details />
|
||||
</RecordContextProvider>,
|
||||
)
|
||||
|
||||
expect(container).toMatchSnapshot()
|
||||
})
|
||||
|
||||
test('renders correctly with no date fields', () => {
|
||||
const record = {
|
||||
id: '123',
|
||||
name: 'Test Album',
|
||||
songCount: 12,
|
||||
duration: 3600,
|
||||
size: 102400,
|
||||
}
|
||||
|
||||
const { container } = render(
|
||||
<RecordContextProvider value={record}>
|
||||
<Details />
|
||||
</RecordContextProvider>,
|
||||
)
|
||||
|
||||
expect(container).toMatchSnapshot()
|
||||
})
|
||||
|
||||
test('renders correctly with year range (start and end years)', () => {
|
||||
const record = {
|
||||
id: '123',
|
||||
name: 'Test Album',
|
||||
songCount: 12,
|
||||
duration: 3600,
|
||||
size: 102400,
|
||||
year: 2018,
|
||||
yearEnd: 2020,
|
||||
}
|
||||
|
||||
const { container } = render(
|
||||
<RecordContextProvider value={record}>
|
||||
<Details />
|
||||
</RecordContextProvider>,
|
||||
)
|
||||
|
||||
expect(container).toMatchSnapshot()
|
||||
})
|
||||
|
||||
test('renders correctly with originalYear range', () => {
|
||||
const record = {
|
||||
id: '123',
|
||||
name: 'Test Album',
|
||||
songCount: 12,
|
||||
duration: 3600,
|
||||
size: 102400,
|
||||
originalYear: 2015,
|
||||
originalYearEnd: 2016,
|
||||
}
|
||||
|
||||
const { container } = render(
|
||||
<RecordContextProvider value={record}>
|
||||
<Details />
|
||||
</RecordContextProvider>,
|
||||
)
|
||||
|
||||
expect(container).toMatchSnapshot()
|
||||
})
|
||||
})
|
||||
})
|
|
@ -13,14 +13,10 @@ import { linkToRecord, useListContext, Loading } from 'react-admin'
|
|||
import { withContentRect } from 'react-measure'
|
||||
import { useDrag } from 'react-dnd'
|
||||
import subsonic from '../subsonic'
|
||||
import {
|
||||
AlbumContextMenu,
|
||||
PlayButton,
|
||||
ArtistLinkField,
|
||||
RangeDoubleField,
|
||||
} from '../common'
|
||||
import { AlbumContextMenu, PlayButton, ArtistLinkField } from '../common'
|
||||
import { DraggableTypes } from '../consts'
|
||||
import clsx from 'clsx'
|
||||
import { AlbumDatesField } from './AlbumDatesField.jsx'
|
||||
|
||||
const useStyles = makeStyles(
|
||||
(theme) => ({
|
||||
|
@ -187,16 +183,7 @@ const AlbumGridTile = ({ showArtist, record, basePath, ...props }) => {
|
|||
{showArtist ? (
|
||||
<ArtistLinkField record={record} className={classes.albumSubtitle} />
|
||||
) : (
|
||||
<RangeDoubleField
|
||||
record={record}
|
||||
source={'year'}
|
||||
symbol1={'♫'}
|
||||
symbol2={'○'}
|
||||
separator={' · '}
|
||||
sortBy={'max_year'}
|
||||
sortByOrder={'DESC'}
|
||||
className={classes.albumSubtitle}
|
||||
/>
|
||||
<AlbumDatesField record={record} className={classes.albumSubtitle} />
|
||||
)}
|
||||
</div>
|
||||
)
|
||||
|
|
|
@ -20,6 +20,7 @@ import {
|
|||
ArtistLinkField,
|
||||
MultiLineTextField,
|
||||
ParticipantsInfo,
|
||||
RangeField,
|
||||
} from '../common'
|
||||
|
||||
const useStyles = makeStyles({
|
||||
|
@ -47,6 +48,20 @@ const AlbumInfo = (props) => {
|
|||
</SingleFieldList>
|
||||
</ArrayField>
|
||||
),
|
||||
date:
|
||||
record?.maxYear && record.maxYear === record.minYear ? (
|
||||
<TextField source={'date'} />
|
||||
) : (
|
||||
<RangeField source={'year'} />
|
||||
),
|
||||
originalDate:
|
||||
record?.maxOriginalYear &&
|
||||
record.maxOriginalYear === record.minOriginalYear ? (
|
||||
<TextField source={'originalDate'} />
|
||||
) : (
|
||||
<RangeField source={'originalYear'} />
|
||||
),
|
||||
releaseDate: <TextField source={'releaseDate'} />,
|
||||
recordLabel: (
|
||||
<FunctionField
|
||||
source={'recordLabel'}
|
||||
|
|
425
ui/src/album/__snapshots__/AlbumDetails.test.jsx.snap
Normal file
425
ui/src/album/__snapshots__/AlbumDetails.test.jsx.snap
Normal file
|
@ -0,0 +1,425 @@
|
|||
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
|
||||
|
||||
exports[`Details component > Desktop view > renders correctly with all date fields 1`] = `
|
||||
<div>
|
||||
<span>
|
||||
resources.album.fields.originalDate Mar 15, 2018
|
||||
</span>
|
||||
·
|
||||
<span>
|
||||
resources.album.fields.releaseDate Jun 15, 2020
|
||||
</span>
|
||||
·
|
||||
<span>
|
||||
12 resources.song.name
|
||||
</span>
|
||||
·
|
||||
<span>
|
||||
<span>
|
||||
01:00:00
|
||||
</span>
|
||||
</span>
|
||||
·
|
||||
<span>
|
||||
<span
|
||||
class="makeStyles-root-6"
|
||||
>
|
||||
100 KB
|
||||
</span>
|
||||
</span>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`Details component > Desktop view > renders correctly with date 1`] = `
|
||||
<div>
|
||||
<span>
|
||||
May 1, 2020
|
||||
</span>
|
||||
·
|
||||
<span>
|
||||
12 resources.song.name
|
||||
</span>
|
||||
·
|
||||
<span>
|
||||
<span>
|
||||
01:00:00
|
||||
</span>
|
||||
</span>
|
||||
·
|
||||
<span>
|
||||
<span
|
||||
class="makeStyles-root-2"
|
||||
>
|
||||
100 KB
|
||||
</span>
|
||||
</span>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`Details component > Desktop view > renders correctly with date and originalDate 1`] = `
|
||||
<div>
|
||||
<span>
|
||||
resources.album.fields.originalDate Mar 15, 2018
|
||||
</span>
|
||||
·
|
||||
<span>
|
||||
12 resources.song.name
|
||||
</span>
|
||||
·
|
||||
<span>
|
||||
<span>
|
||||
01:00:00
|
||||
</span>
|
||||
</span>
|
||||
·
|
||||
<span>
|
||||
<span
|
||||
class="makeStyles-root-4"
|
||||
>
|
||||
100 KB
|
||||
</span>
|
||||
</span>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`Details component > Desktop view > renders correctly with just year range 1`] = `
|
||||
<div>
|
||||
<span>
|
||||
12 resources.song.name
|
||||
</span>
|
||||
·
|
||||
<span>
|
||||
<span>
|
||||
01:00:00
|
||||
</span>
|
||||
</span>
|
||||
·
|
||||
<span>
|
||||
<span
|
||||
class="makeStyles-root-1"
|
||||
>
|
||||
100 KB
|
||||
</span>
|
||||
</span>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`Details component > Desktop view > renders correctly with originalDate 1`] = `
|
||||
<div>
|
||||
<span>
|
||||
resources.album.fields.originalDate Mar 15, 2018
|
||||
</span>
|
||||
·
|
||||
<span>
|
||||
12 resources.song.name
|
||||
</span>
|
||||
·
|
||||
<span>
|
||||
<span>
|
||||
01:00:00
|
||||
</span>
|
||||
</span>
|
||||
·
|
||||
<span>
|
||||
<span
|
||||
class="makeStyles-root-3"
|
||||
>
|
||||
100 KB
|
||||
</span>
|
||||
</span>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`Details component > Desktop view > renders correctly with releaseDate 1`] = `
|
||||
<div>
|
||||
<span>
|
||||
resources.album.fields.releaseDate Jun 15, 2020
|
||||
</span>
|
||||
·
|
||||
<span>
|
||||
12 resources.song.name
|
||||
</span>
|
||||
·
|
||||
<span>
|
||||
<span>
|
||||
01:00:00
|
||||
</span>
|
||||
</span>
|
||||
·
|
||||
<span>
|
||||
<span
|
||||
class="makeStyles-root-5"
|
||||
>
|
||||
100 KB
|
||||
</span>
|
||||
</span>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`Details component > Mobile view > renders correctly with all date fields 1`] = `
|
||||
<div>
|
||||
<span>
|
||||
♫ Mar 15, 2018
|
||||
</span>
|
||||
·
|
||||
<span>
|
||||
○ Jun 15, 2020
|
||||
</span>
|
||||
·
|
||||
<span>
|
||||
12 resources.song.name
|
||||
</span>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`Details component > Mobile view > renders correctly with date 1`] = `
|
||||
<div>
|
||||
<span>
|
||||
♫ May 1, 2020
|
||||
</span>
|
||||
·
|
||||
<span>
|
||||
12 resources.song.name
|
||||
</span>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`Details component > Mobile view > renders correctly with date and originalDate 1`] = `
|
||||
<div>
|
||||
<span>
|
||||
♫ Mar 15, 2018
|
||||
</span>
|
||||
·
|
||||
<span>
|
||||
12 resources.song.name
|
||||
</span>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`Details component > Mobile view > renders correctly with just year range 1`] = `
|
||||
<div>
|
||||
<span>
|
||||
12 resources.song.name
|
||||
</span>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`Details component > Mobile view > renders correctly with no date fields 1`] = `
|
||||
<div>
|
||||
<span>
|
||||
12 resources.song.name
|
||||
</span>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`Details component > Mobile view > renders correctly with originalDate 1`] = `
|
||||
<div>
|
||||
<span>
|
||||
♫ Mar 15, 2018
|
||||
</span>
|
||||
·
|
||||
<span>
|
||||
12 resources.song.name
|
||||
</span>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`Details component > Mobile view > renders correctly with originalYear range 1`] = `
|
||||
<div>
|
||||
<span>
|
||||
12 resources.song.name
|
||||
</span>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`Details component > Mobile view > renders correctly with releaseDate 1`] = `
|
||||
<div>
|
||||
<span>
|
||||
Jun 15, 2020
|
||||
</span>
|
||||
·
|
||||
<span>
|
||||
12 resources.song.name
|
||||
</span>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`Details component > Mobile view > renders correctly with year range (start and end years) 1`] = `
|
||||
<div>
|
||||
<span>
|
||||
12 resources.song.name
|
||||
</span>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`Details component > renders correctly in mobile view 1`] = `
|
||||
<div>
|
||||
<span>
|
||||
♫ Mar 15, 2018
|
||||
</span>
|
||||
·
|
||||
<span>
|
||||
○ Jun 15, 2020
|
||||
</span>
|
||||
·
|
||||
<span>
|
||||
12 resources.song.name
|
||||
</span>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`Details component > renders correctly with all date fields 1`] = `
|
||||
<div>
|
||||
<span>
|
||||
resources.album.fields.originalDate Mar 15, 2018
|
||||
</span>
|
||||
·
|
||||
<span>
|
||||
resources.album.fields.releaseDate Jun 15, 2020
|
||||
</span>
|
||||
·
|
||||
<span>
|
||||
12 resources.song.name
|
||||
</span>
|
||||
·
|
||||
<span>
|
||||
<span>
|
||||
01:00:00
|
||||
</span>
|
||||
</span>
|
||||
·
|
||||
<span>
|
||||
<span
|
||||
class="makeStyles-root-6"
|
||||
>
|
||||
100 KB
|
||||
</span>
|
||||
</span>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`Details component > renders correctly with date 1`] = `
|
||||
<div>
|
||||
<span>
|
||||
May 1, 2020
|
||||
</span>
|
||||
·
|
||||
<span>
|
||||
12 resources.song.name
|
||||
</span>
|
||||
·
|
||||
<span>
|
||||
<span>
|
||||
01:00:00
|
||||
</span>
|
||||
</span>
|
||||
·
|
||||
<span>
|
||||
<span
|
||||
class="makeStyles-root-2"
|
||||
>
|
||||
100 KB
|
||||
</span>
|
||||
</span>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`Details component > renders correctly with date and originalDate 1`] = `
|
||||
<div>
|
||||
<span>
|
||||
resources.album.fields.originalDate Mar 15, 2018
|
||||
</span>
|
||||
·
|
||||
<span>
|
||||
12 resources.song.name
|
||||
</span>
|
||||
·
|
||||
<span>
|
||||
<span>
|
||||
01:00:00
|
||||
</span>
|
||||
</span>
|
||||
·
|
||||
<span>
|
||||
<span
|
||||
class="makeStyles-root-4"
|
||||
>
|
||||
100 KB
|
||||
</span>
|
||||
</span>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`Details component > renders correctly with just year range 1`] = `
|
||||
<div>
|
||||
<span>
|
||||
12 resources.song.name
|
||||
</span>
|
||||
·
|
||||
<span>
|
||||
<span>
|
||||
01:00:00
|
||||
</span>
|
||||
</span>
|
||||
·
|
||||
<span>
|
||||
<span
|
||||
class="makeStyles-root-1"
|
||||
>
|
||||
100 KB
|
||||
</span>
|
||||
</span>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`Details component > renders correctly with originalDate 1`] = `
|
||||
<div>
|
||||
<span>
|
||||
resources.album.fields.originalDate Mar 15, 2018
|
||||
</span>
|
||||
·
|
||||
<span>
|
||||
12 resources.song.name
|
||||
</span>
|
||||
·
|
||||
<span>
|
||||
<span>
|
||||
01:00:00
|
||||
</span>
|
||||
</span>
|
||||
·
|
||||
<span>
|
||||
<span
|
||||
class="makeStyles-root-3"
|
||||
>
|
||||
100 KB
|
||||
</span>
|
||||
</span>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`Details component > renders correctly with releaseDate 1`] = `
|
||||
<div>
|
||||
<span>
|
||||
resources.album.fields.releaseDate Jun 15, 2020
|
||||
</span>
|
||||
·
|
||||
<span>
|
||||
12 resources.song.name
|
||||
</span>
|
||||
·
|
||||
<span>
|
||||
<span>
|
||||
01:00:00
|
||||
</span>
|
||||
</span>
|
||||
·
|
||||
<span>
|
||||
<span
|
||||
class="makeStyles-root-5"
|
||||
>
|
||||
100 KB
|
||||
</span>
|
||||
</span>
|
||||
</div>
|
||||
`;
|
|
@ -50,7 +50,7 @@ const ArtistDetails = (props) => {
|
|||
)
|
||||
}
|
||||
|
||||
const AlbumShowLayout = (props) => {
|
||||
const ArtistShowLayout = (props) => {
|
||||
const showContext = useShowContext(props)
|
||||
const record = useRecordContext()
|
||||
const { width } = props
|
||||
|
@ -98,7 +98,7 @@ const ArtistShow = withWidth()((props) => {
|
|||
const controllerProps = useShowController(props)
|
||||
return (
|
||||
<ShowContextProvider value={controllerProps}>
|
||||
<AlbumShowLayout {...controllerProps} />
|
||||
<ArtistShowLayout {...controllerProps} />
|
||||
</ShowContextProvider>
|
||||
)
|
||||
})
|
||||
|
|
|
@ -1,50 +0,0 @@
|
|||
import React from 'react'
|
||||
import PropTypes from 'prop-types'
|
||||
import { useRecordContext } from 'react-admin'
|
||||
import { formatRange } from '../common'
|
||||
|
||||
export const RangeDoubleField = ({
|
||||
className,
|
||||
source,
|
||||
symbol1,
|
||||
symbol2,
|
||||
separator,
|
||||
...rest
|
||||
}) => {
|
||||
const record = useRecordContext(rest)
|
||||
const yearRange = formatRange(record, source).toString()
|
||||
const releases = [record.releases]
|
||||
const releaseDate = [record.releaseDate]
|
||||
const releaseYear = releaseDate.toString().substring(0, 4)
|
||||
let subtitle = yearRange
|
||||
|
||||
if (releases > 1) {
|
||||
subtitle = [
|
||||
[yearRange && symbol1, yearRange].join(' '),
|
||||
['(', releases, ')))'].join(' '),
|
||||
].join(separator)
|
||||
}
|
||||
|
||||
if (
|
||||
yearRange !== releaseYear &&
|
||||
yearRange.length > 0 &&
|
||||
releaseYear.length > 0
|
||||
) {
|
||||
subtitle = [
|
||||
[yearRange && symbol1, yearRange].join(' '),
|
||||
[symbol2, releaseYear].join(' '),
|
||||
].join(separator)
|
||||
}
|
||||
|
||||
return <span className={className}>{subtitle}</span>
|
||||
}
|
||||
|
||||
RangeDoubleField.propTypes = {
|
||||
label: PropTypes.string,
|
||||
record: PropTypes.object,
|
||||
source: PropTypes.string.isRequired,
|
||||
}
|
||||
|
||||
RangeDoubleField.defaultProps = {
|
||||
addLabel: true,
|
||||
}
|
|
@ -13,7 +13,6 @@ export * from './Pagination'
|
|||
export * from './PlayButton'
|
||||
export * from './QuickFilter'
|
||||
export * from './RangeField'
|
||||
export * from './RangeDoubleField'
|
||||
export * from './ShuffleAllButton'
|
||||
export * from './SimpleList'
|
||||
export * from './SizeField'
|
||||
|
|
|
@ -58,6 +58,7 @@
|
|||
"genre": "Genre",
|
||||
"compilation": "Compilation",
|
||||
"year": "Year",
|
||||
"date": "Recording Date",
|
||||
"originalDate": "Original",
|
||||
"releaseDate": "Released",
|
||||
"releases": "Release |||| Releases",
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue