issue-152 wasn't quiet solved correctly it showed all parts #162
@@ -14,7 +14,7 @@ export const schema = gql`
|
|||||||
}
|
}
|
||||||
|
|
||||||
type Query {
|
type Query {
|
||||||
parts: [Part!]!
|
parts(userName: String): [Part!]!
|
||||||
part(id: String!): Part
|
part(id: String!): Part
|
||||||
partByUserAndTitle(userName: String!, partTitle: String!): Part
|
partByUserAndTitle(userName: String!, partTitle: String!): Part
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,8 +7,18 @@ import {
|
|||||||
import { requireAuth } from 'src/lib/auth'
|
import { requireAuth } from 'src/lib/auth'
|
||||||
import { requireOwnership } from 'src/lib/owner'
|
import { requireOwnership } from 'src/lib/owner'
|
||||||
|
|
||||||
export const parts = () => {
|
export const parts = ({ userName }) => {
|
||||||
return db.part.findMany({ where: { deleted: false } })
|
if (!userName) {
|
||||||
|
return db.part.findMany({ where: { deleted: false } })
|
||||||
|
}
|
||||||
|
return db.part.findMany({
|
||||||
|
where: {
|
||||||
|
deleted: false,
|
||||||
|
user: {
|
||||||
|
userName,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
export const part = ({ id }) => {
|
export const part = ({ id }) => {
|
||||||
|
|||||||
@@ -10,11 +10,12 @@ const PartsList = ({ parts, shouldFilterPartsWithoutImage = false }) => {
|
|||||||
// related issue-104
|
// related issue-104
|
||||||
const filteredParts = useMemo(
|
const filteredParts = useMemo(
|
||||||
() =>
|
() =>
|
||||||
shouldFilterPartsWithoutImage
|
(shouldFilterPartsWithoutImage
|
||||||
? parts.filter(({ mainImage }) => mainImage)
|
? parts.filter(({ mainImage }) => mainImage)
|
||||||
: [...parts]
|
: [...parts]
|
||||||
// sort should probably be done on the service, but the filtering is temp too
|
)
|
||||||
.sort((a, b) => new Date(b.updatedAt) - new Date(a.updatedAt)),
|
// sort should probably be done on the service, but the filtering is temp too
|
||||||
|
.sort((a, b) => new Date(b.updatedAt) - new Date(a.updatedAt)),
|
||||||
[parts, shouldFilterPartsWithoutImage]
|
[parts, shouldFilterPartsWithoutImage]
|
||||||
)
|
)
|
||||||
return (
|
return (
|
||||||
|
|||||||
47
web/src/components/PartsOfUserCell/PartsOfUserCell.js
Normal file
47
web/src/components/PartsOfUserCell/PartsOfUserCell.js
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
import { Link, routes } from '@redwoodjs/router'
|
||||||
|
|
||||||
|
import Parts from 'src/components/Parts'
|
||||||
|
|
||||||
|
export const QUERY = gql`
|
||||||
|
query PARTS_OF_USER($userName: String!) {
|
||||||
|
parts(userName: $userName) {
|
||||||
|
id
|
||||||
|
title
|
||||||
|
mainImage
|
||||||
|
createdAt
|
||||||
|
updatedAt
|
||||||
|
user {
|
||||||
|
image
|
||||||
|
userName
|
||||||
|
}
|
||||||
|
Reaction {
|
||||||
|
emote
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`
|
||||||
|
|
||||||
|
export const Loading = () => <div>Loading...</div>
|
||||||
|
|
||||||
|
export const Empty = () => {
|
||||||
|
return (
|
||||||
|
<div className="rw-text-center">
|
||||||
|
{'No parts yet. '}
|
||||||
|
<Link to={routes.newPart()} className="rw-link">
|
||||||
|
{'Create one?'}
|
||||||
|
</Link>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export const Success = ({
|
||||||
|
parts,
|
||||||
|
variables: { shouldFilterPartsWithoutImage },
|
||||||
|
}) => {
|
||||||
|
return (
|
||||||
|
<Parts
|
||||||
|
parts={parts}
|
||||||
|
shouldFilterPartsWithoutImage={shouldFilterPartsWithoutImage}
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
}
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
// Define your own mock data here:
|
||||||
|
export const standard = (/* vars, { ctx, req } */) => ({
|
||||||
|
partsOfUser: {
|
||||||
|
id: 42,
|
||||||
|
},
|
||||||
|
})
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
import { Loading, Empty, Failure, Success } from './PartsOfUserCell'
|
||||||
|
import { standard } from './PartsOfUserCell.mock'
|
||||||
|
|
||||||
|
export const loading = () => {
|
||||||
|
return Loading ? <Loading /> : null
|
||||||
|
}
|
||||||
|
|
||||||
|
export const empty = () => {
|
||||||
|
return Empty ? <Empty /> : null
|
||||||
|
}
|
||||||
|
|
||||||
|
export const failure = () => {
|
||||||
|
return Failure ? <Failure error={new Error('Oh no')} /> : null
|
||||||
|
}
|
||||||
|
|
||||||
|
export const success = () => {
|
||||||
|
return Success ? <Success {...standard()} /> : null
|
||||||
|
}
|
||||||
|
|
||||||
|
export default { title: 'Cells/PartsOfUserCell' }
|
||||||
26
web/src/components/PartsOfUserCell/PartsOfUserCell.test.js
Normal file
26
web/src/components/PartsOfUserCell/PartsOfUserCell.test.js
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
import { render, screen } from '@redwoodjs/testing'
|
||||||
|
import { Loading, Empty, Failure, Success } from './PartsOfUserCell'
|
||||||
|
import { standard } from './PartsOfUserCell.mock'
|
||||||
|
|
||||||
|
describe('PartsOfUserCell', () => {
|
||||||
|
test('Loading renders successfully', () => {
|
||||||
|
render(<Loading />)
|
||||||
|
// Use screen.debug() to see output
|
||||||
|
expect(screen.getByText('Loading...')).toBeInTheDocument()
|
||||||
|
})
|
||||||
|
|
||||||
|
test('Empty renders successfully', async () => {
|
||||||
|
render(<Empty />)
|
||||||
|
expect(screen.getByText('Empty')).toBeInTheDocument()
|
||||||
|
})
|
||||||
|
|
||||||
|
test('Failure renders successfully', async () => {
|
||||||
|
render(<Failure error={new Error('Oh no')} />)
|
||||||
|
expect(screen.getByText(/Oh no/i)).toBeInTheDocument()
|
||||||
|
})
|
||||||
|
|
||||||
|
test('Success renders successfully', async () => {
|
||||||
|
render(<Success partsOfUser={standard().partsOfUser} />)
|
||||||
|
expect(screen.getByText(/42/i)).toBeInTheDocument()
|
||||||
|
})
|
||||||
|
})
|
||||||
@@ -5,7 +5,7 @@ import Editor from 'rich-markdown-editor'
|
|||||||
import ImageUploader from 'src/components/ImageUploader'
|
import ImageUploader from 'src/components/ImageUploader'
|
||||||
import Button from 'src/components/Button'
|
import Button from 'src/components/Button'
|
||||||
import ProfileTextInput from 'src/components/ProfileTextInput'
|
import ProfileTextInput from 'src/components/ProfileTextInput'
|
||||||
import PartsCell from 'src/components/PartsCell'
|
import PartsOfUser from 'src/components/PartsOfUserCell'
|
||||||
|
|
||||||
const UserProfile = ({ user, isEditable, loading, onSave, error, parts }) => {
|
const UserProfile = ({ user, isEditable, loading, onSave, error, parts }) => {
|
||||||
const { currentUser } = useAuth()
|
const { currentUser } = useAuth()
|
||||||
@@ -93,7 +93,7 @@ const UserProfile = ({ user, isEditable, loading, onSave, error, parts }) => {
|
|||||||
</div>
|
</div>
|
||||||
<div className="mt-10">
|
<div className="mt-10">
|
||||||
<h3 className="text-3xl text-gray-500 font-ropa-sans">Parts:</h3>
|
<h3 className="text-3xl text-gray-500 font-ropa-sans">Parts:</h3>
|
||||||
<PartsCell />
|
<PartsOfUser userName={user?.userName} />
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
</>
|
</>
|
||||||
|
|||||||
Reference in New Issue
Block a user