1
0
Fork 0
mirror of https://github.com/plankanban/planka.git synced 2025-07-19 05:09:43 +02:00

feat: Improve UX of comment actions (#924)

Closes #915
This commit is contained in:
Holden Hu 2024-10-28 04:17:08 +08:00 committed by GitHub
parent f372113def
commit 814b5810ac
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 53 additions and 34 deletions

View file

@ -10,7 +10,7 @@ import { focusEnd } from '../../../utils/element-helpers';
import styles from './CommentEdit.module.scss'; import styles from './CommentEdit.module.scss';
const CommentEdit = React.forwardRef(({ children, defaultData, onUpdate }, ref) => { const CommentEdit = React.forwardRef(({ defaultData, onUpdate, text, actions }, ref) => {
const [t] = useTranslation(); const [t] = useTranslation();
const [isOpened, setIsOpened] = useState(false); const [isOpened, setIsOpened] = useState(false);
const [data, handleFieldChange, setData] = useForm(null); const [data, handleFieldChange, setData] = useForm(null);
@ -76,7 +76,12 @@ const CommentEdit = React.forwardRef(({ children, defaultData, onUpdate }, ref)
}, [isOpened]); }, [isOpened]);
if (!isOpened) { if (!isOpened) {
return children; return (
<>
{actions}
{text}
</>
);
} }
return ( return (
@ -101,9 +106,10 @@ const CommentEdit = React.forwardRef(({ children, defaultData, onUpdate }, ref)
}); });
CommentEdit.propTypes = { CommentEdit.propTypes = {
children: PropTypes.element.isRequired,
defaultData: PropTypes.object.isRequired, // eslint-disable-line react/forbid-prop-types defaultData: PropTypes.object.isRequired, // eslint-disable-line react/forbid-prop-types
onUpdate: PropTypes.func.isRequired, onUpdate: PropTypes.func.isRequired,
text: PropTypes.element.isRequired,
actions: PropTypes.element.isRequired,
}; };
export default React.memo(CommentEdit); export default React.memo(CommentEdit);

View file

@ -31,44 +31,51 @@ const ItemComment = React.memo(
<User name={user.name} avatarUrl={user.avatarUrl} /> <User name={user.name} avatarUrl={user.avatarUrl} />
</span> </span>
<div className={classNames(styles.content)}> <div className={classNames(styles.content)}>
<div className={styles.title}> <CommentEdit
<span className={styles.author}>{user.name}</span> ref={commentEdit}
<span className={styles.date}> defaultData={data}
{t(`format:${getDateFormat(createdAt)}`, { onUpdate={onUpdate}
postProcess: 'formatDate', text={
value: createdAt,
})}
</span>
</div>
<CommentEdit ref={commentEdit} defaultData={data} onUpdate={onUpdate}>
<>
<div className={styles.text}> <div className={styles.text}>
<Markdown linkTarget="_blank">{data.text}</Markdown> <Markdown linkTarget="_blank">{data.text}</Markdown>
</div> </div>
{canEdit && ( }
<Comment.Actions> actions={
<Comment.Action <div className={styles.title}>
as="button" <span>
content={t('action.edit')} <span className={styles.author}>{user.name}</span>
disabled={!isPersisted} <span className={styles.date}>
onClick={handleEditClick} {t(`format:${getDateFormat(createdAt)}`, {
/> postProcess: 'formatDate',
<DeletePopup value: createdAt,
title="common.deleteComment" })}
content="common.areYouSureYouWantToDeleteThisComment" </span>
buttonContent="action.deleteComment" </span>
onConfirm={onDelete} {canEdit && (
> <Comment.Actions>
<Comment.Action <Comment.Action
as="button" as="button"
content={t('action.delete')} content={t('action.edit')}
disabled={!isPersisted} disabled={!isPersisted}
onClick={handleEditClick}
/> />
</DeletePopup> <DeletePopup
</Comment.Actions> title="common.deleteComment"
)} content="common.areYouSureYouWantToDeleteThisComment"
</> buttonContent="action.deleteComment"
</CommentEdit> onConfirm={onDelete}
>
<Comment.Action
as="button"
content={t('action.delete')}
disabled={!isPersisted}
/>
</DeletePopup>
</Comment.Actions>
)}
</div>
}
/>
</div> </div>
</Comment> </Comment>
); );

View file

@ -38,6 +38,12 @@
.title { .title {
padding-bottom: 4px; padding-bottom: 4px;
display: flex;
align-items: center;
justify-content: space-between;
position: sticky;
top: -1em;
background: #f5f6f7;
} }
.user { .user {