]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-21656 Remove legacy Dropdown component
authorJeremy Davis <jeremy.davis@sonarsource.com>
Mon, 4 Mar 2024 13:55:28 +0000 (14:55 +0100)
committersonartech <sonartech@sonarsource.com>
Tue, 5 Mar 2024 20:02:30 +0000 (20:02 +0000)
server/sonar-web/src/main/js/components/controls/Dropdown.tsx [deleted file]
server/sonar-web/src/main/js/components/controls/Toggler.tsx [deleted file]
server/sonar-web/src/main/js/components/controls/__tests__/Toggler-test.tsx [deleted file]
server/sonar-web/src/main/js/components/issue/components/IssueActionsBar.tsx
server/sonar-web/src/main/js/components/issue/components/IssueCommentAction.tsx [deleted file]
server/sonar-web/src/main/js/components/issue/popups/CommentForm.tsx [deleted file]
server/sonar-web/src/main/js/components/issue/popups/CommentPopup.tsx [deleted file]

diff --git a/server/sonar-web/src/main/js/components/controls/Dropdown.tsx b/server/sonar-web/src/main/js/components/controls/Dropdown.tsx
deleted file mode 100644 (file)
index 96cf2ef..0000000
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2024 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
- */
-import * as React from 'react';
-import { Popup, PopupPlacement } from '../ui/popups';
-import ScreenPositionFixer from './ScreenPositionFixer';
-
-interface OverlayProps {
-  className?: string;
-  children: React.ReactNode;
-  noPadding?: boolean;
-  placement?: PopupPlacement;
-  useEventBoundary?: boolean;
-}
-
-export class DropdownOverlay extends React.Component<OverlayProps> {
-  get placement() {
-    return this.props.placement || PopupPlacement.Bottom;
-  }
-
-  renderPopup = (leftFix?: number, topFix?: number) => (
-    <Popup
-      arrowStyle={
-        leftFix !== undefined && topFix !== undefined
-          ? { transform: `translate(${-leftFix}px, ${-topFix}px)` }
-          : undefined
-      }
-      className={this.props.className}
-      noPadding={this.props.noPadding}
-      placement={this.placement}
-      style={
-        leftFix !== undefined && topFix !== undefined
-          ? { marginLeft: `calc(50% + ${leftFix}px)` }
-          : undefined
-      }
-      useEventBoundary={this.props.useEventBoundary}
-    >
-      {this.props.children}
-    </Popup>
-  );
-
-  render() {
-    if (this.placement === PopupPlacement.Bottom) {
-      return (
-        <ScreenPositionFixer>
-          {({ leftFix, topFix }) => this.renderPopup(leftFix, topFix)}
-        </ScreenPositionFixer>
-      );
-    }
-    return this.renderPopup();
-  }
-}
diff --git a/server/sonar-web/src/main/js/components/controls/Toggler.tsx b/server/sonar-web/src/main/js/components/controls/Toggler.tsx
deleted file mode 100644 (file)
index 125d7a6..0000000
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2024 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
- */
-import * as React from 'react';
-import DocumentClickHandler from './DocumentClickHandler';
-import EscKeydownHandler from './EscKeydownHandler';
-import FocusOutHandler from './FocusOutHandler';
-import OutsideClickHandler from './OutsideClickHandler';
-import UpDownKeyboardHanlder from './UpDownKeyboardHandler';
-
-interface Props {
-  children?: React.ReactNode;
-  closeOnClick?: boolean;
-  closeOnClickOutside?: boolean;
-  closeOnEscape?: boolean;
-  closeOnFocusOut?: boolean;
-  navigateWithKeyboard?: boolean;
-  onRequestClose: () => void;
-  open: boolean;
-  overlay: React.ReactNode;
-}
-
-export default class Toggler extends React.Component<Props> {
-  renderOverlay() {
-    const {
-      closeOnClick = false,
-      closeOnClickOutside = true,
-      closeOnEscape = true,
-      closeOnFocusOut = true,
-      navigateWithKeyboard = true,
-      onRequestClose,
-      overlay,
-    } = this.props;
-
-    let renderedOverlay = overlay;
-
-    if (navigateWithKeyboard) {
-      renderedOverlay = <UpDownKeyboardHanlder>{renderedOverlay}</UpDownKeyboardHanlder>;
-    }
-
-    if (closeOnFocusOut) {
-      renderedOverlay = (
-        <FocusOutHandler onFocusOut={onRequestClose}>{renderedOverlay}</FocusOutHandler>
-      );
-    }
-
-    if (closeOnEscape) {
-      renderedOverlay = (
-        <EscKeydownHandler onKeydown={onRequestClose}>{renderedOverlay}</EscKeydownHandler>
-      );
-    }
-
-    if (closeOnClick) {
-      return (
-        <DocumentClickHandler onClick={onRequestClose}>{renderedOverlay}</DocumentClickHandler>
-      );
-    } else if (closeOnClickOutside) {
-      return (
-        <OutsideClickHandler onClickOutside={onRequestClose}>{renderedOverlay}</OutsideClickHandler>
-      );
-    }
-    return renderedOverlay;
-  }
-
-  render() {
-    return (
-      <>
-        {this.props.children}
-        {this.props.open && this.renderOverlay()}
-      </>
-    );
-  }
-}
diff --git a/server/sonar-web/src/main/js/components/controls/__tests__/Toggler-test.tsx b/server/sonar-web/src/main/js/components/controls/__tests__/Toggler-test.tsx
deleted file mode 100644 (file)
index 4b8352f..0000000
+++ /dev/null
@@ -1,237 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2024 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
- */
-import { render } from '@testing-library/react';
-import userEvent from '@testing-library/user-event';
-import { UserEvent } from '@testing-library/user-event/dist/types/setup/setup';
-import * as React from 'react';
-import { byRole } from '../../../helpers/testSelector';
-import Toggler from '../Toggler';
-
-const ui = {
-  toggleButton: byRole('button', { name: 'toggle' }),
-  outButton: byRole('button', { name: 'out' }),
-  overlayButton: byRole('button', { name: 'overlay' }),
-  nextOverlayButton: byRole('button', { name: 'next overlay' }),
-  overlayTextarea: byRole('textbox'),
-  overlayLatButton: byRole('button', { name: 'last' }),
-};
-
-async function openToggler(user: UserEvent) {
-  await user.click(ui.toggleButton.get());
-  expect(ui.overlayButton.get()).toBeInTheDocument();
-}
-
-async function focusOut() {
-  await userEvent.click(ui.outButton.get());
-}
-
-it('should handle key up/down', async () => {
-  const user = userEvent.setup({ delay: null });
-  const rerender = renderToggler(
-    {},
-    <>
-      <textarea name="test-area" />
-      <button type="button">last</button>
-    </>,
-  );
-
-  await openToggler(user);
-  await user.keyboard('{ArrowUp}');
-  expect(ui.overlayLatButton.get()).toHaveFocus();
-
-  await user.keyboard('{ArrowUp}');
-  expect(ui.overlayTextarea.get()).toHaveFocus();
-
-  // Focus does not escape multiline input
-  await user.keyboard('{ArrowDown}');
-  expect(ui.overlayTextarea.get()).toHaveFocus();
-  await user.keyboard('{ArrowUp}');
-  expect(ui.overlayTextarea.get()).toHaveFocus();
-
-  // Escapt textarea
-  await user.keyboard('{Tab}');
-
-  // No focus change when using shortcut
-  await user.keyboard('{Control>}{ArrowUp}{/Control}');
-  expect(ui.overlayLatButton.get()).toHaveFocus();
-
-  await user.keyboard('{ArrowDown}');
-  expect(ui.overlayButton.get()).toHaveFocus();
-
-  await user.keyboard('{ArrowDown}');
-  expect(ui.nextOverlayButton.get()).toHaveFocus();
-
-  rerender();
-  await openToggler(user);
-  await user.keyboard('{ArrowDown}');
-  expect(ui.overlayButton.get()).toHaveFocus();
-});
-
-it('should handle escape correclty', async () => {
-  const user = userEvent.setup({ delay: null });
-  const rerender = renderToggler({
-    closeOnEscape: true,
-    closeOnClick: false,
-    closeOnClickOutside: false,
-    closeOnFocusOut: false,
-  });
-
-  await openToggler(user);
-
-  await user.keyboard('{Escape}');
-  expect(ui.overlayButton.query()).not.toBeInTheDocument();
-
-  rerender({ closeOnEscape: false });
-  await openToggler(user);
-
-  await user.keyboard('{Escape}');
-  expect(ui.overlayButton.get()).toBeInTheDocument();
-});
-
-it('should handle focus correctly', async () => {
-  const user = userEvent.setup({ delay: null });
-  const rerender = renderToggler({
-    closeOnEscape: false,
-    closeOnClick: false,
-    closeOnClickOutside: false,
-    closeOnFocusOut: true,
-  });
-
-  await openToggler(user);
-
-  await focusOut();
-  expect(ui.overlayButton.query()).not.toBeInTheDocument();
-
-  rerender({ closeOnFocusOut: false });
-  await openToggler(user);
-
-  await focusOut();
-  expect(ui.overlayButton.get()).toBeInTheDocument();
-});
-
-it('should handle click correctly', async () => {
-  const user = userEvent.setup({ delay: null });
-  const rerender = renderToggler({
-    closeOnEscape: false,
-    closeOnClick: true,
-    closeOnClickOutside: false,
-    closeOnFocusOut: false,
-  });
-
-  await openToggler(user);
-
-  await user.click(ui.outButton.get());
-  expect(ui.overlayButton.query()).not.toBeInTheDocument();
-
-  await openToggler(user);
-
-  await user.click(ui.overlayButton.get());
-  expect(ui.overlayButton.query()).not.toBeInTheDocument();
-
-  rerender({ closeOnClick: false });
-  await openToggler(user);
-
-  await user.click(ui.outButton.get());
-  expect(ui.overlayButton.get()).toBeInTheDocument();
-});
-
-it('should handle click outside correctly', async () => {
-  const user = userEvent.setup({ delay: null });
-  const rerender = renderToggler({
-    closeOnEscape: false,
-    closeOnClick: false,
-    closeOnClickOutside: true,
-    closeOnFocusOut: false,
-  });
-
-  await openToggler(user);
-
-  await user.click(ui.overlayButton.get());
-  expect(await ui.overlayButton.find()).toBeInTheDocument();
-
-  await user.click(ui.outButton.get());
-  expect(ui.overlayButton.query()).not.toBeInTheDocument();
-
-  rerender({ closeOnClickOutside: false });
-  await openToggler(user);
-
-  await user.click(ui.outButton.get());
-  expect(ui.overlayButton.get()).toBeInTheDocument();
-});
-
-it('should open/close correctly when default props is applied', async () => {
-  const user = userEvent.setup({ delay: null });
-  renderToggler();
-
-  await openToggler(user);
-
-  // Should not close when on overlay
-  await user.click(ui.overlayButton.get());
-  expect(await ui.overlayButton.find()).toBeInTheDocument();
-
-  // Focus out should close
-  await focusOut();
-  expect(ui.overlayButton.query()).not.toBeInTheDocument();
-
-  await openToggler(user);
-
-  // Escape should close
-  await user.keyboard('{Escape}');
-  expect(ui.overlayButton.query()).not.toBeInTheDocument();
-
-  await openToggler(user);
-
-  // Click should close (focus out is trigger first)
-  await user.click(ui.outButton.get());
-  expect(ui.overlayButton.query()).not.toBeInTheDocument();
-});
-
-function renderToggler(override?: Partial<Toggler['props']>, additionalOverlay?: React.ReactNode) {
-  function App(props: Partial<Toggler['props']>) {
-    const [open, setOpen] = React.useState(false);
-
-    return (
-      <>
-        <Toggler
-          onRequestClose={() => setOpen(false)}
-          open={open}
-          overlay={
-            <div className="popup">
-              <button type="button">overlay</button>
-              <button type="button">next overlay</button>
-              {additionalOverlay}
-            </div>
-          }
-          {...props}
-        >
-          <button onClick={() => setOpen(true)} type="button">
-            toggle
-          </button>
-        </Toggler>
-        <button type="button">out</button>
-      </>
-    );
-  }
-
-  const { rerender } = render(<App {...override} />);
-  return function (reoverride?: Partial<Toggler['props']>) {
-    return rerender(<App {...override} {...reoverride} />);
-  };
-}
index 2e14e9daf2d87f08a4a365fe62ecc78e4497fe6f..6daa8e98ec95621cb13ca6039cb83a806cddde81 100644 (file)
@@ -22,7 +22,6 @@ import * as React from 'react';
 import { IssueActions } from '../../../types/issues';
 import { Issue } from '../../../types/types';
 import IssueAssign from './IssueAssign';
-import IssueCommentAction from './IssueCommentAction';
 import IssueTags from './IssueTags';
 import IssueTransition from './IssueTransition';
 import SonarLintBadge from './SonarLintBadge';
@@ -50,16 +49,7 @@ export default function IssueActionsBar(props: Readonly<Props>) {
     canSetTags,
   } = props;
 
-  const [commentPlaceholder, setCommentPlaceholder] = React.useState('');
-
-  const toggleComment = (open: boolean, placeholder = '') => {
-    setCommentPlaceholder(placeholder);
-
-    togglePopup('comment', open);
-  };
-
   const canAssign = issue.actions.includes(IssueActions.Assign);
-  const canComment = issue.actions.includes(IssueActions.Comment);
   const tagsPopupOpen = currentPopup === 'edit-tags' && canSetTags;
 
   return (
@@ -107,16 +97,6 @@ export default function IssueActionsBar(props: Readonly<Props>) {
           </li>
         )}
       </ul>
-
-      {canComment && (
-        <IssueCommentAction
-          commentPlaceholder={commentPlaceholder}
-          currentPopup={currentPopup === 'comment'}
-          issueKey={issue.key}
-          onChange={onChange}
-          toggleComment={toggleComment}
-        />
-      )}
     </div>
   );
 }
diff --git a/server/sonar-web/src/main/js/components/issue/components/IssueCommentAction.tsx b/server/sonar-web/src/main/js/components/issue/components/IssueCommentAction.tsx
deleted file mode 100644 (file)
index cae4574..0000000
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2024 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
- */
-import * as React from 'react';
-import { addIssueComment, deleteIssueComment, editIssueComment } from '../../../api/issues';
-import Toggler from '../../../components/controls/Toggler';
-import { Issue } from '../../../types/types';
-import { updateIssue } from '../actions';
-import CommentPopup from '../popups/CommentPopup';
-
-interface Props {
-  commentPlaceholder: string;
-  currentPopup?: boolean;
-  issueKey: string;
-  onChange: (issue: Issue) => void;
-  toggleComment: (open: boolean, placeholder?: string, autoTriggered?: boolean) => void;
-}
-
-export default class IssueCommentAction extends React.PureComponent<Props> {
-  addComment = (text: string) => {
-    updateIssue(this.props.onChange, addIssueComment({ issue: this.props.issueKey, text }));
-    this.handleClose();
-  };
-
-  handleEditComment = (comment: string, text: string) => {
-    updateIssue(this.props.onChange, editIssueComment({ comment, text }));
-  };
-
-  handleDeleteComment = (comment: string) => {
-    updateIssue(this.props.onChange, deleteIssueComment({ comment }));
-  };
-
-  handleClose = () => {
-    this.props.toggleComment(false);
-  };
-
-  render() {
-    return (
-      <div className="issue-meta dropdown">
-        <Toggler
-          closeOnClickOutside={false}
-          onRequestClose={this.handleClose}
-          open={!!this.props.currentPopup}
-          overlay={
-            <CommentPopup
-              onComment={this.addComment}
-              placeholder={this.props.commentPlaceholder}
-              toggleComment={this.props.toggleComment}
-            />
-          }
-        />
-      </div>
-    );
-  }
-}
diff --git a/server/sonar-web/src/main/js/components/issue/popups/CommentForm.tsx b/server/sonar-web/src/main/js/components/issue/popups/CommentForm.tsx
deleted file mode 100644 (file)
index 617bbed..0000000
+++ /dev/null
@@ -1,95 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2024 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
- */
-import * as React from 'react';
-import { KeyboardKeys } from '../../../helpers/keycodes';
-import { translate } from '../../../helpers/l10n';
-import FormattingTips from '../../common/FormattingTips';
-import { Button, ResetButtonLink } from '../../controls/buttons';
-
-export interface CommentFormProps {
-  comment?: string;
-  onCancel: () => void;
-  onSaveComment: (comment: string) => void;
-  placeholder?: string;
-  showFormatHelp: boolean;
-  autoTriggered?: boolean;
-}
-
-export default function CommentForm(props: CommentFormProps) {
-  const { comment, placeholder, showFormatHelp, autoTriggered } = props;
-  const [editComment, setEditComment] = React.useState(comment || '');
-
-  return (
-    <>
-      <div className="issue-comment-form-text">
-        <textarea
-          autoFocus
-          className="sw-w-full"
-          style={{ resize: 'vertical' }}
-          placeholder={placeholder}
-          aria-label={translate('issue.comment.enter_comment')}
-          onChange={(event: React.ChangeEvent<HTMLTextAreaElement>) => {
-            setEditComment(event.target.value);
-          }}
-          onKeyDown={(event: React.KeyboardEvent) => {
-            if (event.nativeEvent.key === KeyboardKeys.Enter && (event.metaKey || event.ctrlKey)) {
-              props.onSaveComment(editComment);
-              setEditComment('');
-            }
-          }}
-          rows={2}
-          value={editComment}
-        />
-      </div>
-      <div className="sw-flex sw-justify-between issue-comment-form-footer">
-        {showFormatHelp && (
-          <div className="issue-comment-form-tips">
-            <FormattingTips />
-          </div>
-        )}
-        <div>
-          <div className="issue-comment-form-actions">
-            <Button
-              className="js-issue-comment-submit"
-              disabled={editComment.trim().length < 1}
-              onClick={() => {
-                props.onSaveComment(editComment);
-                setEditComment('');
-              }}
-            >
-              {comment ? translate('save') : translate('issue.comment.formlink')}
-            </Button>
-            <ResetButtonLink
-              className="js-issue-comment-cancel little-spacer-left"
-              aria-label={
-                comment
-                  ? translate('issue.comment.edit.cancel')
-                  : translate('issue.comment.add_comment.cancel')
-              }
-              onClick={props.onCancel}
-            >
-              {autoTriggered ? translate('skip') : translate('cancel')}
-            </ResetButtonLink>
-          </div>
-        </div>
-      </div>
-    </>
-  );
-}
diff --git a/server/sonar-web/src/main/js/components/issue/popups/CommentPopup.tsx b/server/sonar-web/src/main/js/components/issue/popups/CommentPopup.tsx
deleted file mode 100644 (file)
index 4c7bc87..0000000
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2024 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
- */
-import * as React from 'react';
-import { DropdownOverlay } from '../../../components/controls/Dropdown';
-import { PopupPlacement } from '../../../components/ui/popups';
-import { IssueComment } from '../../../types/types';
-import CommentForm from './CommentForm';
-
-export interface CommentPopupProps {
-  comment?: Pick<IssueComment, 'markdown'>;
-  onComment: (text: string) => void;
-  toggleComment: (visible: boolean) => void;
-  placeholder: string;
-  placement?: PopupPlacement;
-}
-
-export default class CommentPopup extends React.PureComponent<CommentPopupProps> {
-  handleCancelClick = () => {
-    this.props.toggleComment(false);
-  };
-
-  render() {
-    const { comment } = this.props;
-
-    return (
-      <DropdownOverlay placement={this.props.placement}>
-        <div className="sw-min-w-abs-500 issue-comment-bubble-popup">
-          <CommentForm
-            placeholder={this.props.placeholder}
-            onCancel={this.handleCancelClick}
-            onSaveComment={this.props.onComment}
-            showFormatHelp
-            comment={comment?.markdown}
-          />
-        </div>
-      </DropdownOverlay>
-    );
-  }
-}