Files
astuto/app/javascript/components/Post/PostP.tsx
2024-02-27 18:32:14 +01:00

278 lines
7.7 KiB
TypeScript

import * as React from 'react';
import ReactMarkdown from 'react-markdown';
import IPost from '../../interfaces/IPost';
import IPostStatus from '../../interfaces/IPostStatus';
import IBoard from '../../interfaces/IBoard';
import ITenantSetting from '../../interfaces/ITenantSetting';
import PostUpdateList from './PostUpdateList';
import PostEditForm from './PostEditForm';
import PostFooter from './PostFooter';
import LikeList from './LikeList';
import ActionBox from './ActionBox';
import LikeButton from '../../containers/LikeButton';
import PostBoardLabel from '../common/PostBoardLabel';
import PostStatusLabel from '../common/PostStatusLabel';
import Comments from '../../containers/Comments';
import Sidebar from '../common/Sidebar';
import PoweredByLink from '../common/PoweredByLink';
import { LikesState } from '../../reducers/likesReducer';
import { CommentsState } from '../../reducers/commentsReducer';
import { PostStatusChangesState } from '../../reducers/postStatusChangesReducer';
import { PostEditFormState } from '../../reducers/currentPostReducer';
import { fromRailsStringToJavascriptDate } from '../../helpers/datetime';
import HttpStatus from '../../constants/http_status';
interface Props {
postId: number;
post: IPost;
editMode: boolean;
editForm: PostEditFormState;
likes: LikesState;
followed: boolean;
comments: CommentsState;
postStatusChanges: PostStatusChangesState;
boards: Array<IBoard>;
postStatuses: Array<IPostStatus>;
isLoggedIn: boolean;
isPowerUser: boolean;
currentUserFullName: string;
currentUserEmail: string;
tenantSetting: ITenantSetting;
authenticityToken: string;
requestPost(postId: number): void;
updatePost(
postId: number,
title: string,
description: string,
boardId: number,
postStatusId: number,
authenticityToken: string,
): Promise<any>;
requestLikes(postId: number): void;
requestFollow(postId: number): void;
requestPostStatusChanges(postId: number): void;
toggleEditMode(): void;
handleChangeEditFormTitle(title: string): void;
handleChangeEditFormDescription(description: string): void;
handleChangeEditFormBoard(boardId: number): void;
handleChangeEditFormPostStatus(postStatusId: number): void;
deletePost(postId: number, authenticityToken: string): Promise<any>;
postStatusChangeSubmitted(
newPostStatusId: number,
userFullName: string,
userEmail: string,
): void;
submitFollow(
postId: number,
isFollow: boolean,
authenticityToken: string,
): void;
}
class PostP extends React.Component<Props> {
constructor(props: Props) {
super(props);
this._handleUpdatePost = this._handleUpdatePost.bind(this);
this._handleDeletePost = this._handleDeletePost.bind(this);
}
componentDidMount() {
const { postId } = this.props;
this.props.requestPost(postId);
this.props.requestLikes(postId);
this.props.requestFollow(postId);
this.props.requestPostStatusChanges(postId);
}
_handleUpdatePost(title: string, description: string, boardId: number, postStatusId: number) {
const {
postId,
post,
currentUserFullName,
currentUserEmail,
authenticityToken,
updatePost,
postStatusChangeSubmitted,
} = this.props;
const oldPostStatusId = post.postStatusId;
updatePost(
postId,
title,
description,
boardId,
postStatusId,
authenticityToken,
).then(res => {
if (res?.status !== HttpStatus.OK) return;
if (postStatusId === oldPostStatusId) return;
postStatusChangeSubmitted(
postStatusId,
currentUserFullName,
currentUserEmail,
);
});
}
_handleDeletePost() {
this.props.deletePost(
this.props.postId,
this.props.authenticityToken
).then(() => window.location.href = `/boards/${this.props.post.boardId}`);
}
render() {
const {
post,
editMode,
editForm,
likes,
followed,
comments,
postStatusChanges,
boards,
postStatuses,
isLoggedIn,
isPowerUser,
currentUserEmail,
tenantSetting,
authenticityToken,
submitFollow,
toggleEditMode,
handleChangeEditFormTitle,
handleChangeEditFormDescription,
handleChangeEditFormBoard,
handleChangeEditFormPostStatus,
} = this.props;
const postUpdates = [
...comments.items.filter(comment => comment.isPostUpdate === true),
...postStatusChanges.items,
].sort(
(a, b) =>
fromRailsStringToJavascriptDate(a.createdAt) < fromRailsStringToJavascriptDate(b.createdAt) ? 1 : -1
);
return (
<div className="postContainer">
<Sidebar>
<PostUpdateList
postUpdates={postUpdates}
postStatuses={postStatuses}
areLoading={comments.areLoading}
error={comments.error}
/>
{
isPowerUser &&
<LikeList
likes={likes.items}
areLoading={likes.areLoading}
error={likes.error}
/>
}
<ActionBox
followed={followed}
submitFollow={() => submitFollow(post.id, !followed, authenticityToken)}
isLoggedIn={isLoggedIn}
/>
{ tenantSetting.show_powered_by && <PoweredByLink /> }
</Sidebar>
<div className="postAndCommentsContainer">
{
editMode ?
<PostEditForm
{...editForm}
handleChangeTitle={handleChangeEditFormTitle}
handleChangeDescription={handleChangeEditFormDescription}
handleChangeBoard={handleChangeEditFormBoard}
handleChangePostStatus={handleChangeEditFormPostStatus}
isPowerUser={isPowerUser}
boards={boards}
postStatuses={postStatuses}
toggleEditMode={toggleEditMode}
handleUpdatePost={this._handleUpdatePost}
/>
:
<>
<div className="postHeader">
<LikeButton
postId={post.id}
likeCount={likes.items.length}
showLikeCount={isPowerUser || tenantSetting.show_vote_count}
liked={likes.items.find(like => like.email === currentUserEmail) ? 1 : 0}
isLoggedIn={isLoggedIn}
authenticityToken={authenticityToken}
/>
<h3>{post.title}</h3>
</div>
<div className="postInfo">
<PostBoardLabel
{...boards.find(board => board.id === post.boardId)}
/>
<PostStatusLabel
{...postStatuses.find(postStatus => postStatus.id === post.postStatusId)}
/>
</div>
<ReactMarkdown
className="postDescription"
disallowedTypes={['heading', 'image', 'html']}
unwrapDisallowed
>
{post.description}
</ReactMarkdown>
<PostFooter
createdAt={post.createdAt}
handleDeletePost={this._handleDeletePost}
toggleEditMode={toggleEditMode}
isPowerUser={isPowerUser}
authorEmail={post.userEmail}
authorFullName={post.userFullName}
currentUserEmail={currentUserEmail}
/>
</>
}
<Comments
postId={this.props.postId}
isLoggedIn={isLoggedIn}
isPowerUser={isPowerUser}
userEmail={currentUserEmail}
authenticityToken={authenticityToken}
/>
</div>
</div>
);
}
}
export default PostP;