issue-167 Add admin parts page

resolves #167
This commit is contained in:
Kurt Hutten
2020-12-19 18:25:44 +11:00
parent ee11f164a3
commit f0cba9c1e5
5 changed files with 182 additions and 1 deletions

View File

@@ -7,6 +7,7 @@ export const schema = gql`
mainImage: String
createdAt: DateTime!
updatedAt: DateTime!
deleted: Boolean!
user: User!
userId: String!
Comment: [Comment]!

View File

@@ -50,7 +50,8 @@ const Routes = () => {
<Route path="/u/{userName}/{partTitle}/ide" page={IdePartPage} name="ide" />
<Private unauthenticated="home" role="admin">
<Route path="/users" page={UsersPage} name="users" />
<Route path="/admin/users" page={UsersPage} name="users" />
<Route path="/admin/parts" page={AdminPartsPage} name="parts" />
</Private>
</Router>
)

View File

@@ -0,0 +1,128 @@
import { useMutation, useFlash } from '@redwoodjs/web'
import { Link, routes } from '@redwoodjs/router'
import { QUERY } from 'src/components/AdminPartsCell'
const DELETE_PART_MUTATION = gql`
mutation DeletePartMutation($id: String!) {
deletePart(id: $id) {
id
}
}
`
const MAX_STRING_LENGTH = 150
const truncate = (text) => {
let output = text
if (text && text.length > MAX_STRING_LENGTH) {
output = output.substring(0, MAX_STRING_LENGTH) + '...'
}
return output
}
const jsonTruncate = (obj) => {
return truncate(JSON.stringify(obj, null, 2))
}
const timeTag = (datetime) => {
return (
<time dateTime={datetime} title={datetime}>
{new Date(datetime).toUTCString()}
</time>
)
}
const checkboxInputTag = (checked) => {
return <input type="checkbox" checked={checked} disabled />
}
const AdminParts = ({ parts }) => {
const { addMessage } = useFlash()
const [deletePart] = useMutation(DELETE_PART_MUTATION, {
onCompleted: () => {
addMessage('Part deleted.', { classes: 'rw-flash-success' })
},
// This refetches the query on the list page. Read more about other ways to
// update the cache over here:
// https://www.apollographql.com/docs/react/data/mutations/#making-all-other-cache-updates
refetchQueries: [{ query: QUERY }],
awaitRefetchQueries: true,
})
const onDeleteClick = (id) => {
if (confirm('Are you sure you want to delete part ' + id + '?')) {
deletePart({ variables: { id } })
}
}
return (
<div className="rw-segment rw-table-wrapper-responsive">
<table className="rw-table">
<thead>
<tr>
<th>Id</th>
<th>Title</th>
<th>Description</th>
<th>Code</th>
<th>Main image</th>
<th>Created at</th>
<th>Updated at</th>
<th>User id</th>
<th>Deleted</th>
<th>&nbsp;</th>
</tr>
</thead>
<tbody>
{parts.map((part) => (
<tr key={part.id}>
<td>{truncate(part.id)}</td>
<td>{truncate(part.title)}</td>
<td>{truncate(part.description)}</td>
<td>{truncate(part.code)}</td>
<td>{truncate(part.mainImage)}</td>
<td>{timeTag(part.createdAt)}</td>
<td>{timeTag(part.updatedAt)}</td>
<td>{truncate(part.userId)}</td>
<td>{checkboxInputTag(part.deleted)}</td>
<td>
<nav className="rw-table-actions">
<Link
to={routes.part({
userName: part?.user?.userName,
partTitle: part?.title,
})}
title={'Show part ' + part.id + ' detail'}
className="rw-button rw-button-small"
>
Show
</Link>
<Link
to={routes.editPart({
userName: part?.user?.userName,
partTitle: part?.title,
})}
title={'Edit part ' + part.id}
className="rw-button rw-button-small rw-button-blue"
>
Edit
</Link>
<a
href="#"
title={'Delete part ' + part.id}
className="rw-button rw-button-small rw-button-red"
onClick={() => onDeleteClick(part.id)}
>
Delete
</a>
</nav>
</td>
</tr>
))}
</tbody>
</table>
</div>
)
}
export default AdminParts

View File

@@ -0,0 +1,39 @@
import { Link, routes } from '@redwoodjs/router'
import AdminParts from 'src/components/AdminParts'
export const QUERY = gql`
query PARTS {
parts {
id
title
description
code
mainImage
createdAt
updatedAt
userId
deleted
user {
userName
}
}
}
`
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 }) => {
return <AdminParts parts={parts} />
}

View File

@@ -0,0 +1,12 @@
import MainLayout from 'src/layouts/MainLayout'
import AdminPartsCell from 'src/components/AdminPartsCell'
const PartsPage = () => {
return (
<MainLayout>
<AdminPartsCell />
</MainLayout>
)
}
export default PartsPage