feat(posts): add edit support for posts (#9666)

This commit is contained in:
gaurav2733 2024-01-19 15:38:50 +05:30 committed by GitHub
parent f993f50a04
commit 45236a89aa
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 125 additions and 18 deletions

View File

@ -1,4 +1,4 @@
import React, { useState } from 'react';
import React, { useEffect, useState } from 'react';
import { Form, Input, Typography, FormInstance, Radio } from 'antd';
import styled from 'styled-components';
import {
@ -21,11 +21,18 @@ const SubFormItem = styled(Form.Item)`
type Props = {
setCreateButtonEnabled: (isEnabled: boolean) => void;
form: FormInstance;
contentType: PostContentType;
};
export default function CreatePostForm({ setCreateButtonEnabled, form }: Props) {
export default function CreatePostForm({ setCreateButtonEnabled, form, contentType }: Props) {
const [postType, setPostType] = useState<PostContentType>(PostContentType.Text);
useEffect(() => {
if (contentType) {
setPostType(contentType);
}
}, [contentType]);
return (
<Form
form={form}

View File

@ -1,4 +1,4 @@
import React, { useState } from 'react';
import React, { useEffect, useState } from 'react';
import { Button, Form, message, Modal } from 'antd';
import CreatePostForm from './CreatePostForm';
import {
@ -11,9 +11,11 @@ import {
} from './constants';
import { useEnterKeyListener } from '../../shared/useEnterKeyListener';
import { MediaType, PostContentType, PostType } from '../../../types.generated';
import { useCreatePostMutation } from '../../../graphql/mutations.generated';
import { useCreatePostMutation, useUpdatePostMutation } from '../../../graphql/mutations.generated';
import { PostEntry } from './PostsListColumns';
type Props = {
editData: PostEntry;
onClose: () => void;
onCreate: (
contentType: string,
@ -22,12 +24,27 @@ type Props = {
link: string | undefined,
location: string | undefined,
) => void;
onEdit: () => void;
};
export default function CreatePostModal({ onClose, onCreate }: Props) {
export default function CreatePostModal({ onClose, onCreate, editData, onEdit }: Props) {
const [createPostMutation] = useCreatePostMutation();
const [updatePostMutation] = useUpdatePostMutation();
const [createButtonEnabled, setCreateButtonEnabled] = useState(false);
const [form] = Form.useForm();
useEffect(() => {
if (editData) {
form.setFieldsValue({
description: editData.description,
title: editData.title,
link: editData.link,
location: editData.imageUrl,
type: editData.contentType,
});
}
}, [editData, form]);
const onCreatePost = () => {
const contentTypeValue = form.getFieldValue(TYPE_FIELD_NAME) ?? PostContentType.Text;
const mediaValue =
@ -75,33 +92,86 @@ export default function CreatePostModal({ onClose, onCreate }: Props) {
onClose();
};
const onUpdatePost = () => {
const contentTypeValue = form.getFieldValue(TYPE_FIELD_NAME) ?? PostContentType.Text;
const mediaValue =
form.getFieldValue(TYPE_FIELD_NAME) && form.getFieldValue(LOCATION_FIELD_NAME)
? {
type: MediaType.Image,
location: form.getFieldValue(LOCATION_FIELD_NAME) ?? null,
}
: null;
updatePostMutation({
variables: {
input: {
urn: editData?.urn,
postType: PostType.HomePageAnnouncement,
content: {
contentType: contentTypeValue,
title: form.getFieldValue(TITLE_FIELD_NAME),
description: form.getFieldValue(DESCRIPTION_FIELD_NAME) ?? null,
link: form.getFieldValue(LINK_FIELD_NAME) ?? null,
media: mediaValue,
},
},
},
})
.then(({ errors }) => {
if (!errors) {
message.success({
content: `Updated Post!`,
duration: 3,
});
onEdit();
form.resetFields();
}
})
.catch((e) => {
message.destroy();
message.error({ content: 'Failed to update Post! An unknown error occured.', duration: 3 });
console.error('Failed to update Post:', e.message);
});
onClose();
};
// Handle the Enter press
useEnterKeyListener({
querySelectorToExecuteClick: '#createPostButton',
});
const onCloseModal = () => {
form.resetFields();
onClose();
};
const titleText = editData ? 'Edit Post' : 'Create new Post';
return (
<Modal
title="Create new Post"
title={titleText}
open
onCancel={onClose}
onCancel={onCloseModal}
footer={
<>
<Button onClick={onClose} type="text">
<Button onClick={onCloseModal} type="text">
Cancel
</Button>
<Button
id={CREATE_POST_BUTTON_ID}
data-testid="create-post-button"
onClick={onCreatePost}
data-testid={!editData ? 'create-post-button' : 'update-post-button'}
onClick={!editData ? onCreatePost : onUpdatePost}
disabled={!createButtonEnabled}
>
Create
{!editData ? 'Create' : 'Update'}
</Button>
</>
}
>
<CreatePostForm setCreateButtonEnabled={setCreateButtonEnabled} form={form} />
<CreatePostForm
setCreateButtonEnabled={setCreateButtonEnabled}
form={form}
contentType={editData?.contentType as PostContentType}
/>
</Modal>
);
}

View File

@ -1,5 +1,5 @@
import React from 'react';
import { DeleteOutlined } from '@ant-design/icons';
import { DeleteOutlined, EditOutlined } from '@ant-design/icons';
import { Dropdown, Menu, message, Modal } from 'antd';
import { MenuIcon } from '../../entity/shared/EntityDropdown/EntityDropdown';
import { useDeletePostMutation } from '../../../graphql/post.generated';
@ -8,9 +8,10 @@ type Props = {
urn: string;
title: string;
onDelete?: () => void;
onEdit?: () => void;
};
export default function PostItemMenu({ title, urn, onDelete }: Props) {
export default function PostItemMenu({ title, urn, onDelete, onEdit }: Props) {
const [deletePostMutation] = useDeletePostMutation();
const deletePost = () => {
@ -53,6 +54,9 @@ export default function PostItemMenu({ title, urn, onDelete }: Props) {
<Menu.Item onClick={onConfirmDelete} key="delete">
<DeleteOutlined /> &nbsp;Delete
</Menu.Item>
<Menu.Item onClick={onEdit} key="edit">
<EditOutlined /> &nbsp;Edit
</Menu.Item>
</Menu>
}
>

View File

@ -51,6 +51,7 @@ export const PostList = () => {
const [page, setPage] = useState(1);
const [isCreatingPost, setIsCreatingPost] = useState(false);
const [editData, setEditData] = useState<PostEntry | undefined>(undefined);
const pageSize = DEFAULT_PAGE_SIZE;
const start = (page - 1) * pageSize;
@ -82,6 +83,16 @@ export const PostList = () => {
}, 2000);
};
const handleEdit = (post: PostEntry) => {
setEditData(post);
setIsCreatingPost(true);
};
const handleClose = () => {
setEditData(undefined);
setIsCreatingPost(false);
};
const allColumns = [
{
title: 'Title',
@ -113,7 +124,7 @@ export const PostList = () => {
width: '5%',
align: 'right' as AlignType,
key: 'menu',
render: PostListMenuColumn(handleDelete),
render: PostListMenuColumn(handleDelete, handleEdit),
},
];
@ -123,6 +134,8 @@ export const PostList = () => {
title: post.content.title,
description: post.content.description,
contentType: post.content.contentType,
link: post.content.link,
imageUrl: post.content.media?.location,
};
});
@ -181,7 +194,9 @@ export const PostList = () => {
)}
{isCreatingPost && (
<CreatePostModal
onClose={() => setIsCreatingPost(false)}
editData={editData as PostEntry}
onClose={handleClose}
onEdit={() => setTimeout(() => refetch(), 2000)}
onCreate={(urn, title, description) => {
addToListPostCache(
client,

View File

@ -9,15 +9,22 @@ export interface PostEntry {
contentType: string;
description: Maybe<string>;
urn: string;
link: string;
imageUrl: string;
}
const PostText = styled.div<{ minWidth?: number }>`
${(props) => props.minWidth !== undefined && `min-width: ${props.minWidth}px;`}
`;
export function PostListMenuColumn(handleDelete: (urn: string) => void) {
export function PostListMenuColumn(handleDelete: (urn: string) => void, handleEdit: (urn: PostEntry) => void) {
return (record: PostEntry) => (
<PostItemMenu title={record.title} urn={record.urn} onDelete={() => handleDelete(record.urn)} />
<PostItemMenu
title={record.title}
urn={record.urn}
onDelete={() => handleDelete(record.urn)}
onEdit={() => handleEdit(record)}
/>
);
}

View File

@ -120,6 +120,10 @@ mutation createPost($input: CreatePostInput!) {
createPost(input: $input)
}
mutation updatePost($input: UpdatePostInput!) {
updatePost(input: $input)
}
mutation updateLineage($input: UpdateLineageInput!) {
updateLineage(input: $input)
}