@adaptabletools/adaptable
Version:
Powerful data-agnostic HTML5 AG Grid extension which provides advanced, cutting-edge functionality to meet all DataGrid requirements
122 lines (121 loc) • 6.83 kB
JavaScript
import * as React from 'react';
import { useSelector } from 'react-redux';
import { Box, Flex, Text } from 'rebass';
import { Icon } from '../../components/icons';
import Panel from '../../components/Panel';
import SimpleButton from '../../components/SimpleButton';
import * as CommentsRedux from '../../Redux/ActionsReducers/CommentsRedux';
import { CommentsAndNotesSelector } from '../../Redux/ActionsReducers/InternalRedux';
import { useAdaptable } from '../AdaptableContext';
import AdaptableInput from '../Components/AdaptableInput';
import FormatHelper from '../../Utilities/Helpers/FormatHelper';
// Edit Mode
// [author] [edit, delete]
// [text-editor] * this is different
// [show-all-comments-button]
// View Mode
// [author] [edit, delete]
// [text]
// [show-all-comments-button]
export const CommentsEditor = (props) => {
const { api } = useAdaptable();
const showCloseButton = api.optionsApi.getCommentOptions()?.showPopupCloseButton ?? true;
const cellAddress = useSelector((state) => CommentsAndNotesSelector(state.Internal));
const userId = React.useMemo(() => {
return api.optionsApi.getUserName();
}, []);
const commentThread = useSelector((state) => CommentsRedux.GetCellCommentSelector(state.Comment, cellAddress));
const isReadOnlyModule = api.entitlementApi.getEntitlementAccessLevelForModule('Comment') === 'ReadOnly';
const [activeEditingComment, setActiveEditingComment] = React.useState(() => {
/**
* When opening the popup and there is only one comment, we want to open it in edit mode.
* This happens usualy when a new comment is added via cell menu.
*/
// if (cellComments?.Comments?.length === 1 && cellComments?.Comments[0].Value === '') {
// return cellComments?.Comments[0].Uuid;
// }
return null;
});
const [newCommentText, setNewCommentText] = React.useState('');
const commentsWrapperRef = React.useRef(null);
const comments = commentThread?.Comments;
const scrollToBottom = () => {
commentsWrapperRef?.current?.scrollTo(0, commentsWrapperRef?.current?.scrollHeight);
};
React.useEffect(() => {
scrollToBottom();
}, []);
if (!commentThread) {
return null;
}
const formatDate = (date, format) => {
return FormatHelper.DateFormatter(date, { Pattern: format });
};
return (React.createElement(Panel, { color: "var(--ab-color-text-on-primary)", onClick: () => props.enableEditMode(), minWidth: 250, className: "ab-CommentPopup", onKeyDown: (event) => {
if (event.key === 'Escape') {
api.commentApi.hideCommentsPopup();
}
} },
showCloseButton && (React.createElement(Flex, null,
React.createElement(Box, { flex: 1 }),
React.createElement(SimpleButton, { onClick: (event) => {
event.stopPropagation();
api.commentApi.hideCommentsPopup();
}, variant: "text", icon: "close" }))),
React.createElement(Flex, { style: {
overflow: 'auto',
maxHeight: 300,
}, flexDirection: "column", ref: commentsWrapperRef }, comments &&
comments.length > 0 &&
comments.map((comment, index) => {
if (!comment) {
return null;
}
const isOwnComment = comment?.Author?.UserName
? comment?.Author?.UserName === userId
: true; // no owner means it's the current user
return (React.createElement(Box, { p: 2, key: comment.Uuid ?? index, className: "ab-Comment" },
React.createElement(Flex, { mb: 2, alignItems: "center" },
React.createElement(Box, null,
React.createElement(Box, { "data-name": "comment-username", fontSize: 3, fontWeight: "bold" }, comment?.Author?.UserName),
comment.Timestamp && (React.createElement(Box, { "data-name": "comment-timestamp", fontSize: 2 }, formatDate(comment.Timestamp, api.commentApi.internalApi.getCommentsDateFormat())))),
React.createElement(Box, { flex: 1 }),
React.createElement(SimpleButton, { variant: "text", icon: "edit", disabled: !isOwnComment || isReadOnlyModule, onClick: () => setActiveEditingComment(comment.Uuid) }),
React.createElement(SimpleButton, { variant: "text", icon: "delete", disabled: !isOwnComment || isReadOnlyModule, onClick: () => {
api.commentApi.deleteComment(comment, cellAddress);
requestAnimationFrame(() => {
props.onRefreshContent();
});
} })),
React.createElement(Box, { onClick: () => setActiveEditingComment(comment.Uuid) }, comment.Uuid === activeEditingComment ? (React.createElement(AdaptableInput, { autoFocus: true, width: "100%", defaultValue: comment.Value, disabled: isReadOnlyModule, onBlur: () => {
if (comment.Uuid === activeEditingComment) {
setActiveEditingComment(null);
}
}, onChange: (event) => {
api.commentApi.editComment({
...comment,
Value: event.target.value,
}, cellAddress);
} })) : (React.createElement(Text, { "data-name": "comment-text" }, comment.Value)))));
})),
React.createElement(AdaptableInput, { autoFocus: !comments || comments.length === 0, value: newCommentText, disabled: isReadOnlyModule, onChange: (event) => {
setNewCommentText(event.target.value);
}, onKeyDown: (event) => {
if (event.key === 'Enter') {
api.commentApi.addComment(newCommentText, cellAddress);
setNewCommentText('');
requestAnimationFrame(() => {
props.onRefreshContent();
scrollToBottom();
});
}
}, mt: 2, mb: "2", width: "100%", placeholder: "Write new Comment" }),
React.createElement(SimpleButton, { width: "100%", variant: "raised", onClick: () => {
api.settingsPanelApi.openSettingsPanel('Comment');
api.internalApi.getAnnotationsService().hidePopup();
} },
React.createElement(Box, { mr: 2 },
React.createElement(Icon, { name: "folder" })),
' ',
"Open all Comments")));
};