diff --git a/ui/src/common/PathField.jsx b/ui/src/common/PathField.jsx
index 115a2ee49..21822878a 100644
--- a/ui/src/common/PathField.jsx
+++ b/ui/src/common/PathField.jsx
@@ -1,24 +1,22 @@
import PropTypes from 'prop-types'
import React from 'react'
-import { useRecordContext } from 'react-admin'
+import { usePermissions, useRecordContext } from 'react-admin'
import config from '../config'
export const PathField = (props) => {
const record = useRecordContext(props)
- return (
-
- {record.libraryPath}
- {config.separator}
- {record.path}
-
- )
+ const { permissions } = usePermissions()
+ let path = permissions === 'admin' ? record.libraryPath : ''
+
+ if (path && path.endsWith(config.separator)) {
+ path = `${path}${record.path}`
+ } else {
+ path = path ? `${path}${config.separator}${record.path}` : record.path
+ }
+
+ return {path}
}
PathField.propTypes = {
- label: PropTypes.string,
record: PropTypes.object,
}
-
-PathField.defaultProps = {
- addLabel: true,
-}
diff --git a/ui/src/common/PathField.test.jsx b/ui/src/common/PathField.test.jsx
new file mode 100644
index 000000000..de8b90899
--- /dev/null
+++ b/ui/src/common/PathField.test.jsx
@@ -0,0 +1,86 @@
+import React from 'react'
+import { render } from '@testing-library/react'
+import { PathField } from './PathField'
+import { usePermissions, useRecordContext } from 'react-admin'
+import config from '../config'
+
+// Mock react-admin hooks
+vi.mock('react-admin', () => ({
+ usePermissions: vi.fn(),
+ useRecordContext: vi.fn(),
+}))
+
+// Mock config
+vi.mock('../config', () => ({
+ default: {
+ separator: '/',
+ },
+}))
+
+describe('PathField', () => {
+ beforeEach(() => {
+ vi.clearAllMocks()
+ })
+
+ it('renders path without libraryPath for non-admin users', () => {
+ // Setup
+ usePermissions.mockReturnValue({ permissions: 'user' })
+ useRecordContext.mockReturnValue({
+ path: 'music/song.mp3',
+ libraryPath: '/data/media',
+ })
+
+ // Act
+ const { container } = render()
+
+ // Assert
+ expect(container.textContent).toBe('music/song.mp3')
+ expect(container.textContent).not.toContain('/data/media')
+ })
+
+ it('renders combined path for admin users when libraryPath does not end with separator', () => {
+ // Setup
+ usePermissions.mockReturnValue({ permissions: 'admin' })
+ useRecordContext.mockReturnValue({
+ path: 'music/song.mp3',
+ libraryPath: '/data/media',
+ })
+
+ // Act
+ const { container } = render()
+
+ // Assert
+ expect(container.textContent).toBe('/data/media/music/song.mp3')
+ })
+
+ it('renders combined path for admin users when libraryPath ends with separator', () => {
+ // Setup
+ usePermissions.mockReturnValue({ permissions: 'admin' })
+ useRecordContext.mockReturnValue({
+ path: 'music/song.mp3',
+ libraryPath: '/data/media/',
+ })
+
+ // Act
+ const { container } = render()
+
+ // Assert
+ expect(container.textContent).toBe('/data/media/music/song.mp3')
+ })
+
+ it('works with a different separator from config', () => {
+ // Setup
+ config.separator = '\\'
+ usePermissions.mockReturnValue({ permissions: 'admin' })
+ useRecordContext.mockReturnValue({
+ path: 'music\\song.mp3',
+ libraryPath: 'C:\\data',
+ })
+
+ // Act
+ const { container } = render()
+
+ // Assert
+ expect(container.textContent).toBe('C:\\data\\music\\song.mp3')
+ })
+})