Improve Post component

This commit is contained in:
riggraz
2019-09-12 18:03:19 +02:00
parent f599471af1
commit e649588211
11 changed files with 50 additions and 36 deletions

View File

@@ -39,8 +39,9 @@ class PostsController < ApplicationController
def update def update
post = Post.find(params[:id]) post = Post.find(params[:id])
if current_user.role == :user && current_user.id != post.user_id if current_user.role == 'user' && current_user.id != post.user_id
render json: I18n.t('errors.unauthorized'), status: :unauthorized render json: I18n.t('errors.unauthorized'), status: :unauthorized
return
end end
post.post_status_id = params[:post][:post_status_id] post.post_status_id = params[:post][:post_status_id]

View File

@@ -1,5 +1,7 @@
import * as React from 'react'; import * as React from 'react';
import PostStatusLabel from '../shared/PostStatusLabel';
import IPostStatus from '../../interfaces/IPostStatus'; import IPostStatus from '../../interfaces/IPostStatus';
interface Props { interface Props {
@@ -26,15 +28,7 @@ const PostListItem = ({ id, title, description, postStatus}: Props) => (
<span className="comment icon"></span> <span className="comment icon"></span>
<span>0 comments</span> <span>0 comments</span>
</div> </div>
{ { postStatus ? <PostStatusLabel {...postStatus} /> : null }
postStatus ?
<div className="postDetailsStatus">
<div className="dot" style={{backgroundColor: postStatus.color}}></div>
<span className="postStatusName">{postStatus.name}</span>
</div>
:
null
}
</div> </div>
</div> </div>
</a> </a>

View File

@@ -1,5 +1,7 @@
import * as React from 'react'; import * as React from 'react';
import PostStatusLabel from '../shared/PostStatusLabel';
interface Props { interface Props {
name: string; name: string;
color: string; color: string;
@@ -19,8 +21,7 @@ const PostStatusListItem = ({
<div className={"postStatusListItemContainer " + `postStatus${name.replace(/ /g, '')}`}> <div className={"postStatusListItemContainer " + `postStatus${name.replace(/ /g, '')}`}>
<a onClick={handleClick} className="postStatusListItemLink"> <a onClick={handleClick} className="postStatusListItemLink">
<div className="postStatusListItem"> <div className="postStatusListItem">
<div className="dot" style={{backgroundColor: color}}></div> <PostStatusLabel id={undefined} name={name} color={color} />
<span className="postStatusName">{name}</span>
</div> </div>
</a> </a>
{ {

View File

@@ -4,6 +4,7 @@ import IPost from '../../interfaces/IPost';
import IPostStatus from '../../interfaces/IPostStatus'; import IPostStatus from '../../interfaces/IPostStatus';
import PostStatusSelect from './PostStatusSelect'; import PostStatusSelect from './PostStatusSelect';
import PostStatusLabel from '../shared/PostStatusLabel';
interface Props { interface Props {
postId: number; postId: number;
@@ -39,9 +40,9 @@ class PostP extends React.Component<Props> {
return ( return (
<div> <div>
<h1>{post.title}</h1> <h2>{post.title}</h2>
{ {
isPowerUser ? isPowerUser && post ?
<PostStatusSelect <PostStatusSelect
postStatuses={postStatuses} postStatuses={postStatuses}
selectedPostStatusId={post.postStatusId} selectedPostStatusId={post.postStatusId}
@@ -50,7 +51,9 @@ class PostP extends React.Component<Props> {
} }
/> />
: :
<span>LLL</span> <PostStatusLabel
{...postStatuses.find(postStatus => postStatus.id === post.postStatusId)}
/>
} }
<p>{post.description}</p> <p>{post.description}</p>

View File

@@ -18,7 +18,7 @@ const PostStatusSelect = ({
handleChange, handleChange,
}: Props) => ( }: Props) => (
<select <select
value={selectedPostStatusId || ''} value={selectedPostStatusId || 'none'}
onChange={ onChange={
(e: FormEvent) => ( (e: FormEvent) => (
handleChange(parseInt((e.target as HTMLSelectElement).value)) handleChange(parseInt((e.target as HTMLSelectElement).value))
@@ -30,7 +30,7 @@ const PostStatusSelect = ({
{postStatus.name} {postStatus.name}
</option> </option>
))} ))}
<option>None</option> <option value="none">None</option>
</select> </select>
); );

View File

@@ -0,0 +1,16 @@
import * as React from 'react';
import IPostStatus from '../../interfaces/IPostStatus';
const PostStatusLabel = ({
id,
name,
color,
}: IPostStatus) => (
<div style={{display: 'flex'}}>
<div className="dot" style={{backgroundColor: color}}></div>
<span className="postStatusName">{name}</span>
</div>
);
export default PostStatusLabel;

View File

@@ -17,6 +17,8 @@ const mapDispatchToProps = (dispatch) => ({
}, },
changePostStatus(postId: number, newPostStatusId: number, authenticityToken: string) { changePostStatus(postId: number, newPostStatusId: number, authenticityToken: string) {
if (isNaN(newPostStatusId)) newPostStatusId = null;
dispatch(changePostStatus(postId, newPostStatusId, authenticityToken)); dispatch(changePostStatus(postId, newPostStatusId, authenticityToken));
}, },
}); });

View File

@@ -9,4 +9,14 @@
.gravatar { .gravatar {
border-radius: 16px; border-radius: 16px;
}
.dot {
width: 16px;
height: 16px;
border-radius: 100%;
margin-top: auto;
margin-bottom: auto;
margin-right: 4px;
} }

View File

@@ -199,16 +199,6 @@
} }
} }
.dot {
width: 16px;
height: 16px;
border-radius: 100%;
margin-top: auto;
margin-bottom: auto;
margin-right: 4px;
}
.infoText { .infoText {
display: block; display: block;
text-align: center; text-align: center;

View File

@@ -34,12 +34,6 @@
border-bottom-width: 1px; border-bottom-width: 1px;
margin-bottom: 8px; margin-bottom: 8px;
} }
.dot {
width: 16px;
height: 16px;
border-radius: 100%;
}
.infoText { .infoText {
text-align: center; text-align: center;
@@ -47,7 +41,6 @@
} }
.columnTitle { .columnTitle {
margin: 0 8px;
font-weight: 700; font-weight: 700;
} }

View File

@@ -8,10 +8,14 @@ RSpec.describe 'posts routing', :aggregate_failures, type: :routing do
expect(post: '/posts').to route_to( expect(post: '/posts').to route_to(
controller: 'posts', action: 'create' controller: 'posts', action: 'create'
) )
expect(get: '/posts/1').to route_to(
controller: 'posts', action: 'show', id: '1'
)
expect(patch: '/posts/1').to route_to(
controller: 'posts', action: 'update', id: '1'
)
expect(get: '/posts/1').not_to be_routable
expect(get: '/posts/1/edit').not_to be_routable expect(get: '/posts/1/edit').not_to be_routable
expect(patch: '/posts/1').not_to be_routable
expect(delete: '/posts/1').not_to be_routable expect(delete: '/posts/1').not_to be_routable
end end
end end