From f701f8d05f64843f7921a95f0b710da0f323d0f5 Mon Sep 17 00:00:00 2001 From: Philip Molares <philip.molares@udo.edu> Date: Mon, 30 Oct 2023 12:23:24 +0100 Subject: [PATCH] refactor: remove show-if in favour of conditionals This prevents a problem where show-if can trigger an error if a value is checked to exist with it. Signed-off-by: Philip Molares <philip.molares@udo.edu> --- frontend/src/app/(editor)/profile/page.tsx | 5 +- .../loading-screen/loading-screen.tsx | 7 +- .../copyable-field/copyable-field.tsx | 7 +- .../copyable/hooks/use-copy-overlay.tsx | 11 +-- .../hedge-doc-logo-horizontal-grey.tsx | 5 +- .../common/icon-button/icon-button.tsx | 7 +- .../components/common/modals/common-modal.tsx | 41 ++++++----- .../create-non-existing-note-hint.tsx | 5 +- .../note-loading-boundary.tsx | 5 +- .../common/pagination/pager-pagination.tsx | 23 +++--- .../renderer-iframe/renderer-iframe.tsx | 7 +- .../__snapshots__/show-if.spec.tsx.snap | 9 --- .../common/show-if/show-if.spec.tsx | 19 ----- .../src/components/common/show-if/show-if.tsx | 21 ------ .../common/user-avatar/user-avatar.tsx | 5 +- .../document-infobar.tsx | 17 ++--- .../editor-pane/tool-bar/tool-bar.tsx | 73 ++++++++++--------- .../upload-image-button.tsx | 5 +- .../sidebar/sidebar-button/sidebar-button.tsx | 5 +- .../sidebar-menu-info-entry.tsx | 5 +- .../aliases-modal/aliases-list-entry.tsx | 9 +-- .../import-markdown-sidebar-entry.tsx | 5 +- .../note-info-line-word-count.tsx | 9 +-- .../permission-entry-user.tsx | 6 +- .../revisions-modal/revision-list-entry.tsx | 7 +- .../share-modal/share-modal.tsx | 21 +++--- .../user-line/user-line.tsx | 5 +- .../editor-page/splitter/splitter.tsx | 7 +- .../table-of-contents/table-of-contents.tsx | 7 +- .../use-build-react-dom-from-toc-ast.tsx | 11 +-- .../error-pages/common-error-page.tsx | 5 +- .../shortcuts-modal/shortcut-line.tsx | 21 +++--- .../version-info-modal/version-info-modal.tsx | 9 +-- .../history-page/entry-menu/entry-menu.tsx | 19 ++--- .../history-toolbar/history-toolbar.tsx | 5 +- .../intro-page/intro-custom-content.tsx | 4 +- .../navigation/sign-in-button.tsx | 17 +++-- .../help-dropdown/submenues/legal-submenu.tsx | 13 ++-- .../translated-dropdown-item.tsx | 5 +- .../note-title-element/note-title-element.tsx | 5 +- .../login-page/guest/guest-card.tsx | 5 +- .../local-login/local-login-card.tsx | 11 +-- .../click-shield/click-shield.tsx | 28 ++++--- .../notifications/ui-notification-toast.tsx | 5 +- .../access-tokens/profile-access-tokens.tsx | 11 +-- .../register-page/register-infos.tsx | 17 +++-- .../document/document-toc-sidebar.tsx | 7 +- .../abcjs/abc-frame.tsx | 7 +- .../flowchart/flowchart.tsx | 7 +- .../graphviz/graphviz-frame.tsx | 7 +- .../mermaid/mermaid-chart.tsx | 7 +- .../vega-lite/vega-lite-chart.tsx | 7 +- 52 files changed, 239 insertions(+), 352 deletions(-) delete mode 100644 frontend/src/components/common/show-if/__snapshots__/show-if.spec.tsx.snap delete mode 100644 frontend/src/components/common/show-if/show-if.spec.tsx delete mode 100644 frontend/src/components/common/show-if/show-if.tsx diff --git a/frontend/src/app/(editor)/profile/page.tsx b/frontend/src/app/(editor)/profile/page.tsx index 428ebb6eb..14a1c5ad6 100644 --- a/frontend/src/app/(editor)/profile/page.tsx +++ b/frontend/src/app/(editor)/profile/page.tsx @@ -7,7 +7,6 @@ */ import { AuthProviderType } from '../../../api/config/types' import { Redirect } from '../../../components/common/redirect' -import { ShowIf } from '../../../components/common/show-if/show-if' import { LandingLayout } from '../../../components/landing-layout/landing-layout' import { ProfileAccessTokens } from '../../../components/profile-page/access-tokens/profile-access-tokens' import { ProfileAccountManagement } from '../../../components/profile-page/account-management/profile-account-management' @@ -35,9 +34,7 @@ const ProfilePage: NextPage = () => { <Row className='h-100 flex justify-content-center'> <Col lg={6}> <ProfileDisplayName /> - <ShowIf condition={userProvider === (AuthProviderType.LOCAL as string)}> - <ProfileChangePassword /> - </ShowIf> + {userProvider === (AuthProviderType.LOCAL as string) && <ProfileChangePassword />} <ProfileAccessTokens /> <ProfileAccountManagement /> </Col> diff --git a/frontend/src/components/application-loader/loading-screen/loading-screen.tsx b/frontend/src/components/application-loader/loading-screen/loading-screen.tsx index c19944370..424e7b24d 100644 --- a/frontend/src/components/application-loader/loading-screen/loading-screen.tsx +++ b/frontend/src/components/application-loader/loading-screen/loading-screen.tsx @@ -1,9 +1,8 @@ /* - * SPDX-FileCopyrightText: 2022 The HedgeDoc developers (see AUTHORS file) + * SPDX-FileCopyrightText: 2023 The HedgeDoc developers (see AUTHORS file) * * SPDX-License-Identifier: AGPL-3.0-only */ -import { ShowIf } from '../../common/show-if/show-if' import styles from '../application-loader.module.scss' import { LoadingAnimation } from './loading-animation' import type { ReactElement } from 'react' @@ -27,9 +26,7 @@ export const LoadingScreen: React.FC<LoadingScreenProps> = ({ errorMessage }) => <LoadingAnimation error={!!errorMessage} /> </span> </div> - <ShowIf condition={!!errorMessage}> - <Alert variant={'danger'}>{errorMessage}</Alert> - </ShowIf> + {errorMessage !== undefined && <Alert variant={'danger'}>{errorMessage}</Alert>} </div> ) } diff --git a/frontend/src/components/common/copyable/copyable-field/copyable-field.tsx b/frontend/src/components/common/copyable/copyable-field/copyable-field.tsx index f458b29e0..6244807f1 100644 --- a/frontend/src/components/common/copyable/copyable-field/copyable-field.tsx +++ b/frontend/src/components/common/copyable/copyable-field/copyable-field.tsx @@ -1,11 +1,10 @@ /* - * SPDX-FileCopyrightText: 2022 The HedgeDoc developers (see AUTHORS file) + * SPDX-FileCopyrightText: 2023 The HedgeDoc developers (see AUTHORS file) * * SPDX-License-Identifier: AGPL-3.0-only */ import { Logger } from '../../../../utils/logger' import { UiIcon } from '../../icons/ui-icon' -import { ShowIf } from '../../show-if/show-if' import { CopyToClipboardButton } from '../copy-to-clipboard-button/copy-to-clipboard-button' import React, { useCallback, useMemo } from 'react' import { Button, FormControl, InputGroup } from 'react-bootstrap' @@ -54,13 +53,13 @@ export const CopyableField: React.FC<CopyableFieldProps> = ({ content, shareOrig <InputGroup.Text> <CopyToClipboardButton variant={'outline-secondary'} content={content} /> </InputGroup.Text> - <ShowIf condition={sharingSupported}> + {sharingSupported && ( <InputGroup.Text> <Button variant='secondary' title={'Share'} onClick={doShareAction}> <UiIcon icon={IconShare} /> </Button> </InputGroup.Text> - </ShowIf> + )} </InputGroup> ) } diff --git a/frontend/src/components/common/copyable/hooks/use-copy-overlay.tsx b/frontend/src/components/common/copyable/hooks/use-copy-overlay.tsx index 9a22fd812..f6b6659d5 100644 --- a/frontend/src/components/common/copyable/hooks/use-copy-overlay.tsx +++ b/frontend/src/components/common/copyable/hooks/use-copy-overlay.tsx @@ -1,10 +1,9 @@ /* - * SPDX-FileCopyrightText: 2022 The HedgeDoc developers (see AUTHORS file) + * SPDX-FileCopyrightText: 2023 The HedgeDoc developers (see AUTHORS file) * * SPDX-License-Identifier: AGPL-3.0-only */ import { Logger } from '../../../../utils/logger' -import { ShowIf } from '../../show-if/show-if' import type { ReactElement, RefObject } from 'react' import React, { useCallback, useEffect, useMemo, useState } from 'react' import { Overlay, Tooltip } from 'react-bootstrap' @@ -64,12 +63,8 @@ export const useCopyOverlay = ( <Overlay target={clickComponent} show={showState !== SHOW_STATE.HIDDEN} placement='top'> {(props) => ( <Tooltip id={`copied_${tooltipId}`} {...props}> - <ShowIf condition={showState === SHOW_STATE.ERROR}> - <Trans i18nKey={'copyOverlay.error'} /> - </ShowIf> - <ShowIf condition={showState === SHOW_STATE.SUCCESS}> - <Trans i18nKey={'copyOverlay.success'} /> - </ShowIf> + {showState === SHOW_STATE.ERROR && <Trans i18nKey={'copyOverlay.error'} />} + {showState === SHOW_STATE.SUCCESS && <Trans i18nKey={'copyOverlay.success'} />} </Tooltip> )} </Overlay> diff --git a/frontend/src/components/common/hedge-doc-logo/hedge-doc-logo-horizontal-grey.tsx b/frontend/src/components/common/hedge-doc-logo/hedge-doc-logo-horizontal-grey.tsx index b22f50004..7c3f83e9b 100644 --- a/frontend/src/components/common/hedge-doc-logo/hedge-doc-logo-horizontal-grey.tsx +++ b/frontend/src/components/common/hedge-doc-logo/hedge-doc-logo-horizontal-grey.tsx @@ -5,7 +5,6 @@ */ import { LogoSize } from './logo-size' import React from 'react' -import { ShowIf } from '../show-if/show-if' interface HedgeDocLogoHorizontalGreyProps { color: 'dark' | 'light' @@ -68,13 +67,13 @@ export const HedgeDocLogoHorizontalGrey: React.FC<HedgeDocLogoHorizontalGreyProp fill='#fff' transform='matrix(0 -3.2849556 -3.2849556 0 254.51398 261.79888)' /> - <ShowIf condition={showText}> + {showText && ( <path d='m914.05273 122.625v70.36133c-4.97999-5.27564-10.96602-9.39883-17.95312-12.375-6.99039-2.97289-14.57179-4.46094-22.74805-4.46094-10.77794 0-20.42618 2.50598-28.9375 7.52539s-15.20529 11.89616-20.07031 20.63086c-4.87159 8.73798-7.30664 18.67703-7.30664 29.82617 0 11.15571 2.43505 21.10062 7.30664 29.83203 4.86502 8.7347 11.55899 15.6095 20.07031 20.62891s18.15956 7.5293 28.9375 7.5293c8.39963 0 16.16843-1.58011 23.30664-4.74024 7.13493-3.16012 13.19251-7.48988 18.17578-12.99219l1.00586 15.50196h16.61133v-167.26758zm-393.29492.002v167.26563h19.51563v-73.5957h95.33984v73.5957h19.51172v-167.26568h-19.51172v75.82813h-95.33984v-75.82813zm724.69919.22071v167.26757h45.4961c32.8594 0 58.0977-7.32308 75.7149-21.9707 17.6172-14.64105 26.4277-35.27334 26.4277-61.88476 0-26.53916-8.8105-47.07674-26.4277-61.60938s-42.8555-21.80273-75.7149-21.80273zm19.5157 17.8457h25.9804c26.4636 0 46.7614 5.70463 60.8867 17.11328 14.1221 11.41522 21.1856 27.56409 21.1856 48.45313 0 20.9613-7.0635 37.20817-21.1856 48.72851-14.1253 11.52363-34.4231 17.28711-60.8867 17.28711h-25.9804zm-248.3301 35.45508c-10.778 0-20.42425 2.50988-28.93557 7.52929-8.51132 5.01942-15.20725 11.89421-20.07226 20.62891-4.87159 8.7347-7.30469 18.6757-7.30469 29.82813 0 11.15242 2.4331 21.09538 7.30469 29.83007 4.86501 8.7347 11.56094 15.61145 20.07226 20.63086 8.51132 5.01942 18.15757 7.52539 28.93557 7.52539 8.1762 0 15.7596-1.48805 22.75-4.46093 6.9871-2.97289 12.9712-7.09608 17.9512-12.375v5.79492c0 15.16664-3.81 27.30097-11.4278 36.41015-7.6244 9.10262-19.3481 13.65625-35.1816 13.65625-6.2447 0-12.04336-1.02121-17.39456-3.06445-5.35447-2.04653-10.11335-4.88956-14.27539-8.5293l-9.14257 15.38672c5.49901 4.08977 11.66853 7.2633 18.50781 9.53321 6.83928 2.2699 14.16041 3.40039 21.96871 3.40039 14.1976 0 26.1478-2.88015 35.8516-8.63867 9.7005-5.76182 17.0402-13.8114 22.0234-24.14258 4.98-10.33447 7.4688-22.37675 7.4688-36.13086v-100.58208h-16.6152l-1.004 15.50195c-4.9799-5.5023-11.0375-9.83206-18.1757-12.99219-7.135-3.16013-14.9051-4.74023-23.3047-4.74023zm591.7656.002c-11.1524 0-21.0973 2.50989-29.832 7.5293-8.7347 5.01612-15.6095 11.89092-20.6289 20.6289-5.0162 8.7347-7.5254 18.67375-7.5254 29.82618 0 11.15242 2.5092 21.09671 7.5254 29.82812 5.0194 8.73798 11.8942 15.61278 20.6289 20.62891 8.7347 5.01941 18.6796 7.52929 29.832 7.52929 8.3996 0 16.1288-1.44899 23.1914-4.34961 7.0627-2.90061 13.1951-6.95092 18.3984-12.15429l-12.8242-12.71094c-3.4952 3.86639-7.6932 6.91014-12.5976 9.14063-4.9078 2.23048-10.2978 3.34765-16.168 3.34765-7.5094 0-14.2007-1.78277-20.0742-5.35351-5.8735-3.56747-10.5026-8.47539-13.8828-14.7168-3.3835-6.2447-5.0723-13.30885-5.0723-21.18945 0-7.95288 1.6888-15.03363 5.0723-21.24219 3.3802-6.20528 8.0093-11.09465 13.8828-14.66211 5.8735-3.57075 12.5648-5.35352 20.0742-5.35352 5.8702 0 11.2602 1.09605 16.168 3.28711 4.9044 2.19435 9.1024 5.25923 12.5976 9.20117l12.8242-12.82421c-5.2033-5.12782-11.3357-9.14236-18.3984-12.04297-7.0626-2.90062-14.7918-4.34766-23.1914-4.34766zm-867.86718.002c-11.00132 0-20.85027 2.494-29.54883 7.47071-8.69856 4.98327-15.53759 11.8057-20.51758 20.46484s-7.47266 18.49149-7.47266 29.49609c0 11.30025 2.65627 21.37042 7.97461 30.2168 5.31178 8.84639 12.65475 15.77942 22.02344 20.79883 9.36541 5.01613 32.11328 7.52539 32.11328 7.52539 7.50941 0 15.29543-1.26551 23.36328-3.79492 8.06457-2.52613 16.14797-7.17049 24.25196-13.9375l-10.81641-13.82617c-5.5023 5.20337-11.59699 8.97814-18.28516 11.32031-6.69474 2.33889-13.04765 3.51172-19.07226 3.51172-10.8535 0-20.12695-3.1801-27.82031-9.53321-7.69337-6.35967-12.46885-14.48142-14.32813-24.36914h94.56055v-7.46875c0-11.22469-2.41783-21.18948-7.25-29.88476-4.83217-8.69856-11.48576-15.53626-19.96094-20.51953-8.47519-4.97671-18.21024-7.47071-29.21484-7.47071zm420.61328 0c-11.0013 0-20.8483 2.494-29.5469 7.47071-8.6985 4.98327-15.5395 11.8057-20.5195 20.46484s-7.4727 18.49149-7.4727 29.49609c0 11.30025 2.6583 21.37042 7.9766 30.2168 5.3118 8.84639 12.6561 15.77942 22.0215 20.79883 9.3654 5.01613 20.0706 7.52539 32.1133 7.52539 7.5094 0 15.2954-1.26551 23.3632-3.79492 8.0646-2.52613 16.15-7.17049 24.254-13.9375l-10.8184-13.82617c-5.5023 5.20337-11.595 8.97814-18.2832 11.32031-6.6915 2.33889-13.0496 3.51172-19.0742 3.51172-10.8535 0-20.125-3.1801-27.8184-9.53321-7.6934-6.35967-12.4708-14.48142-14.3301-24.36914h94.5606v-7.46875c0-11.22469-2.4179-21.18948-7.25-29.88476-4.8322-8.69856-11.4838-15.53626-19.959-20.51953-8.4752-4.97671-18.2122-7.47071-29.2168-7.47071zm311.2109 0c-11.1524 0-21.0914 2.50598-29.8261 7.52539-8.738 5.01942-15.6134 11.89617-20.6329 20.63086-5.0161 8.7347-7.5273 18.67704-7.5273 29.82618 0 11.15242 2.5112 21.09733 7.5273 29.83203 5.0195 8.73469 11.8949 15.60949 20.6329 20.6289 8.7347 5.01942 18.6737 7.52539 29.8261 7.52539 11.1492 0 21.0935-2.50597 29.8282-7.52539 8.7347-5.01941 15.6095-11.89421 20.6289-20.6289 5.0194-8.7347 7.5254-18.67961 7.5254-29.83203 0-11.14914-2.506-21.09148-7.5254-29.82618-5.0194-8.73469-11.8942-15.61144-20.6289-20.63086-8.7347-5.01941-18.679-7.52539-29.8282-7.52539zm-454.0488 16.72251c7.5061 0 14.2001 1.78472 20.0703 5.35547 5.8735 3.56746 10.5026 8.45816 13.8828 14.66015 3.3835 6.20857 5.0743 13.29127 5.0743 21.24415 0 7.8806-1.6908 14.9428-5.0743 21.1875-3.3802 6.2447-8.0093 11.14995-13.8828 14.7207-5.8702 3.56746-12.5642 5.35156-20.0703 5.35156-7.5094 0-14.202-1.7841-20.07226-5.35156-5.8735-3.57075-10.50259-8.476-13.88281-14.7207-3.38679-6.2447-5.07422-13.3069-5.07422-21.1875 0-7.95288 1.68743-15.03558 5.07422-21.24415 3.38022-6.20199 8.00931-11.09269 13.88281-14.66015 5.87026-3.57075 12.56286-5.35547 20.07226-5.35547zm-143.29296.002c7.50941 0 14.20009 1.7841 20.07031 5.35157 5.8735 3.57074 10.50321 8.45878 13.88672 14.66406 3.38022 6.20856 5.07226 13.29064 5.07226 21.24023 0 7.88061-1.69204 14.94476-5.07226 21.18946-3.38351 6.2447-8.01322 11.15128-13.88672 14.71875-5.87022 3.57074-12.5609 5.35546-20.07031 5.35546s-14.2001-1.78472-20.07032-5.35546c-5.8735-3.56747-10.50259-8.47405-13.88281-14.71875-3.3835-6.2447-5.07617-13.30885-5.07617-21.18946 0-7.94959 1.69267-15.03167 5.07617-21.24023 3.38022-6.20528 8.00931-11.09332 13.88281-14.66406 5.87022-3.56747 12.56091-5.35157 20.07032-5.35157zm-134.5918.002c9.73661 0 17.98823 3.06487 24.75195 9.20117 6.76373 6.13301 10.96566 14.06675 12.60157 23.80664h-75.60352c1.63591-9.58879 5.94845-17.4887 12.93555-23.69727 6.9871-6.20528 15.42673-9.31054 25.31445-9.31054zm420.61526 0c9.7366 0 17.9882 3.06487 24.7519 9.20117 6.7638 6.13301 10.9657 14.06675 12.6016 23.80664h-75.6035c1.6359-9.58879 5.9484-17.4887 12.9355-23.69727 6.9871-6.20528 15.4268-9.31054 25.3145-9.31054zm311.3183 0c7.5062 0 14.2021 1.78081 20.0723 5.35156 5.8735 3.57075 10.5013 8.45878 13.8848 14.66406 3.3802 6.20528 5.0722 13.28736 5.0722 21.24024 0 7.8806-1.692 14.94475-5.0722 21.18945-3.3835 6.2447-8.0113 11.148-13.8848 14.71875-5.8702 3.56746-12.5661 5.35156-20.0723 5.35156-7.5094 0-14.2001-1.7841-20.0703-5.35156-5.8735-3.57075-10.5026-8.47405-13.8828-14.71875-3.3868-6.2447-5.0742-13.30885-5.0742-21.18945 0-7.95288 1.6874-15.03496 5.0742-21.24024 3.3802-6.20528 8.0093-11.09331 13.8828-14.66406 5.8702-3.57075 12.5609-5.35156 20.0703-5.35156z' fill={color === 'light' ? '#333' : '#fff'} strokeWidth='3.28496' /> - </ShowIf> + )} </g> </svg> ) diff --git a/frontend/src/components/common/icon-button/icon-button.tsx b/frontend/src/components/common/icon-button/icon-button.tsx index 046d36c6e..744f4c478 100644 --- a/frontend/src/components/common/icon-button/icon-button.tsx +++ b/frontend/src/components/common/icon-button/icon-button.tsx @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2022 The HedgeDoc developers (see AUTHORS file) + * SPDX-FileCopyrightText: 2023 The HedgeDoc developers (see AUTHORS file) * * SPDX-License-Identifier: AGPL-3.0-only */ @@ -7,7 +7,6 @@ import { concatCssClasses } from '../../../utils/concat-css-classes' import type { PropsWithDataTestId } from '../../../utils/test-id' import { testId } from '../../../utils/test-id' import { UiIcon } from '../icons/ui-icon' -import { ShowIf } from '../show-if/show-if' import styles from './icon-button.module.scss' import React, { useMemo } from 'react' import type { ButtonProps } from 'react-bootstrap' @@ -52,9 +51,7 @@ export const IconButton: React.FC<IconButtonProps> = ({ <span className={`${styles['icon-part']}`}> <UiIcon size={iconSize} icon={icon} className={'icon'} /> </span> - <ShowIf condition={!!children}> - <span className={`${styles['text-part']}`}>{children}</span> - </ShowIf> + {children !== undefined && <span className={`${styles['text-part']}`}>{children}</span>} </Button> ) } diff --git a/frontend/src/components/common/modals/common-modal.tsx b/frontend/src/components/common/modals/common-modal.tsx index 9bab6992e..84f618b15 100644 --- a/frontend/src/components/common/modals/common-modal.tsx +++ b/frontend/src/components/common/modals/common-modal.tsx @@ -8,7 +8,6 @@ import type { PropsWithDataCypressId } from '../../../utils/cypress-attribute' import { cypressId } from '../../../utils/cypress-attribute' import { testId } from '../../../utils/test-id' import { UiIcon } from '../icons/ui-icon' -import { ShowIf } from '../show-if/show-if' import type { PropsWithChildren, ReactElement } from 'react' import React, { Fragment, useMemo } from 'react' import { Modal } from 'react-bootstrap' @@ -66,25 +65,27 @@ export const CommonModal: React.FC<PropsWithChildren<CommonModalProps>> = ({ return titleI18nKey !== undefined ? <Trans i18nKey={titleI18nKey} /> : <span>{title}</span> }, [titleI18nKey, title]) + if (!show) { + return null + } + return ( - <ShowIf condition={show}> - <Modal - {...cypressId(props)} - show={show} - onHide={onHide} - animation={true} - {...testId('commonModal')} - dialogClassName={concatCssClasses(additionalClasses)} - size={modalSize}> - <Modal.Header closeButton={!!showCloseButton}> - <Modal.Title> - <UiIcon icon={titleIcon} nbsp={true} /> - {titleElement} - </Modal.Title> - {additionalTitleElement ?? <Fragment />} - </Modal.Header> - {children} - </Modal> - </ShowIf> + <Modal + {...cypressId(props)} + show={show} + onHide={onHide} + animation={true} + {...testId('commonModal')} + dialogClassName={concatCssClasses(additionalClasses)} + size={modalSize}> + <Modal.Header closeButton={!!showCloseButton}> + <Modal.Title> + <UiIcon icon={titleIcon} nbsp={true} /> + {titleElement} + </Modal.Title> + {additionalTitleElement ?? <Fragment />} + </Modal.Header> + {children} + </Modal> ) } diff --git a/frontend/src/components/common/note-loading-boundary/create-non-existing-note-hint.tsx b/frontend/src/components/common/note-loading-boundary/create-non-existing-note-hint.tsx index 991efc2e5..f898e5ac8 100644 --- a/frontend/src/components/common/note-loading-boundary/create-non-existing-note-hint.tsx +++ b/frontend/src/components/common/note-loading-boundary/create-non-existing-note-hint.tsx @@ -6,7 +6,6 @@ import { createNoteWithPrimaryAlias } from '../../../api/notes' import { testId } from '../../../utils/test-id' import { UiIcon } from '../icons/ui-icon' -import { ShowIf } from '../show-if/show-if' import React, { useCallback, useEffect } from 'react' import { Alert, Button } from 'react-bootstrap' import { @@ -85,9 +84,7 @@ export const CreateNonExistingNoteHint: React.FC<CreateNonExistingNoteHintProps> className='mx-2' onClick={onClickHandler} {...testId('createNoteButton')}> - <ShowIf condition={returnState.loading}> - <UiIcon icon={IconArrowRepeat} className={'me-2'} spin={true} /> - </ShowIf> + {returnState.loading && <UiIcon icon={IconArrowRepeat} className={'me-2'} spin={true} />} <Trans i18nKey={'noteLoadingBoundary.createNote.create'} /> </Button> </div> diff --git a/frontend/src/components/common/note-loading-boundary/note-loading-boundary.tsx b/frontend/src/components/common/note-loading-boundary/note-loading-boundary.tsx index 37891660f..87b2807be 100644 --- a/frontend/src/components/common/note-loading-boundary/note-loading-boundary.tsx +++ b/frontend/src/components/common/note-loading-boundary/note-loading-boundary.tsx @@ -10,7 +10,6 @@ import { Logger } from '../../../utils/logger' import { LoadingScreen } from '../../application-loader/loading-screen/loading-screen' import { CommonErrorPage } from '../../error-pages/common-error-page' import { CustomAsyncLoadingBoundary } from '../async-loading-boundary/custom-async-loading-boundary' -import { ShowIf } from '../show-if/show-if' import { CreateNonExistingNoteHint } from './create-non-existing-note-hint' import { useLoadNoteFromServer } from './hooks/use-load-note-from-server' import type { PropsWithChildren } from 'react' @@ -59,9 +58,9 @@ export const NoteLoadingBoundary: React.FC<PropsWithChildren<NoteIdProps>> = ({ <CommonErrorPage titleI18nKey={`${errorI18nKeyPrefix}.title`} descriptionI18nKey={`${errorI18nKeyPrefix}.description`}> - <ShowIf condition={error instanceof ApiError && error.statusCode === 404}> + {error instanceof ApiError && error.statusCode === 404 && ( <CreateNonExistingNoteHint onNoteCreated={loadNoteFromServer} noteId={noteId} /> - </ShowIf> + )} </CommonErrorPage> ) }, [error, loadNoteFromServer, noteId]) diff --git a/frontend/src/components/common/pagination/pager-pagination.tsx b/frontend/src/components/common/pagination/pager-pagination.tsx index 97b9d77b4..dafbefc21 100644 --- a/frontend/src/components/common/pagination/pager-pagination.tsx +++ b/frontend/src/components/common/pagination/pager-pagination.tsx @@ -1,9 +1,8 @@ /* - * SPDX-FileCopyrightText: 2022 The HedgeDoc developers (see AUTHORS file) + * SPDX-FileCopyrightText: 2023 The HedgeDoc developers (see AUTHORS file) * * SPDX-License-Identifier: AGPL-3.0-only */ -import { ShowIf } from '../show-if/show-if' import { PagerItem } from './pager-item' import React, { useEffect, useMemo, useState } from 'react' import { Pagination } from 'react-bootstrap' @@ -70,17 +69,21 @@ export const PagerPagination: React.FC<PaginationProps> = ({ return ( <Pagination dir='ltr'> - <ShowIf condition={correctedLowerPageIndex > 0}> - <PagerItem key={0} index={0} onClick={setPageIndex} /> - <Pagination.Ellipsis disabled /> - </ShowIf> + {correctedLowerPageIndex > 0 && ( + <> + <PagerItem key={0} index={0} onClick={setPageIndex} /> + <Pagination.Ellipsis disabled /> + </> + )} {paginationItemsBefore} <Pagination.Item active>{correctedPageIndex + 1}</Pagination.Item> {paginationItemsAfter} - <ShowIf condition={correctedUpperPageIndex < lastPageIndex}> - <Pagination.Ellipsis disabled /> - <PagerItem key={lastPageIndex} index={lastPageIndex} onClick={setPageIndex} /> - </ShowIf> + {correctedUpperPageIndex < lastPageIndex && ( + <> + <Pagination.Ellipsis disabled /> + <PagerItem key={lastPageIndex} index={lastPageIndex} onClick={setPageIndex} /> + </> + )} </Pagination> ) } diff --git a/frontend/src/components/common/renderer-iframe/renderer-iframe.tsx b/frontend/src/components/common/renderer-iframe/renderer-iframe.tsx index abe822be6..cf8fe8409 100644 --- a/frontend/src/components/common/renderer-iframe/renderer-iframe.tsx +++ b/frontend/src/components/common/renderer-iframe/renderer-iframe.tsx @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2022 The HedgeDoc developers (see AUTHORS file) + * SPDX-FileCopyrightText: 2023 The HedgeDoc developers (see AUTHORS file) * * SPDX-License-Identifier: AGPL-3.0-only */ @@ -19,7 +19,6 @@ import type { SetScrollStateMessage } from '../../render-page/window-post-message-communicator/rendering-message' import { CommunicationMessageType } from '../../render-page/window-post-message-communicator/rendering-message' -import { ShowIf } from '../show-if/show-if' import { WaitSpinner } from '../wait-spinner/wait-spinner' import { useEffectOnRenderTypeChange } from './hooks/use-effect-on-render-type-change' import { useForceRenderPageUrlOnIframeLoadCallback } from './hooks/use-force-render-page-url-on-iframe-load-callback' @@ -176,9 +175,7 @@ export const RendererIframe: React.FC<RendererIframeProps> = ({ return ( <Fragment> - <ShowIf condition={!rendererReady && showWaitSpinner}> - <WaitSpinner /> - </ShowIf> + {!rendererReady && showWaitSpinner && <WaitSpinner />} <iframe style={{ height: `${frameHeight}px` }} {...cypressId('documentIframe')} diff --git a/frontend/src/components/common/show-if/__snapshots__/show-if.spec.tsx.snap b/frontend/src/components/common/show-if/__snapshots__/show-if.spec.tsx.snap deleted file mode 100644 index 2829b934f..000000000 --- a/frontend/src/components/common/show-if/__snapshots__/show-if.spec.tsx.snap +++ /dev/null @@ -1,9 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`ShowIf does not render child if condition is false 1`] = `<div />`; - -exports[`ShowIf renders child if condition is true 1`] = ` -<div> - test -</div> -`; diff --git a/frontend/src/components/common/show-if/show-if.spec.tsx b/frontend/src/components/common/show-if/show-if.spec.tsx deleted file mode 100644 index 39347aedf..000000000 --- a/frontend/src/components/common/show-if/show-if.spec.tsx +++ /dev/null @@ -1,19 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2023 The HedgeDoc developers (see AUTHORS file) - * - * SPDX-License-Identifier: AGPL-3.0-only - */ -import { ShowIf } from './show-if' -import { render } from '@testing-library/react' - -describe('ShowIf', () => { - it('renders child if condition is true', () => { - const view = render(<ShowIf condition={true}>test</ShowIf>) - expect(view.container).toMatchSnapshot() - }) - - it('does not render child if condition is false', () => { - const view = render(<ShowIf condition={false}>test</ShowIf>) - expect(view.container).toMatchSnapshot() - }) -}) diff --git a/frontend/src/components/common/show-if/show-if.tsx b/frontend/src/components/common/show-if/show-if.tsx deleted file mode 100644 index e6257fff3..000000000 --- a/frontend/src/components/common/show-if/show-if.tsx +++ /dev/null @@ -1,21 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2022 The HedgeDoc developers (see AUTHORS file) - * - * SPDX-License-Identifier: AGPL-3.0-only - */ -import type { PropsWithChildren } from 'react' -import React, { Fragment } from 'react' - -export interface ShowIfProps { - condition: boolean -} - -/** - * Renders the children if the condition is met. - * - * @param children The children to show if the condition is met. - * @param condition If the children should be shown - */ -export const ShowIf: React.FC<PropsWithChildren<ShowIfProps>> = ({ children, condition }) => { - return condition ? <Fragment>{children}</Fragment> : null -} diff --git a/frontend/src/components/common/user-avatar/user-avatar.tsx b/frontend/src/components/common/user-avatar/user-avatar.tsx index 728f71595..6294daeb5 100644 --- a/frontend/src/components/common/user-avatar/user-avatar.tsx +++ b/frontend/src/components/common/user-avatar/user-avatar.tsx @@ -4,7 +4,6 @@ * SPDX-License-Identifier: AGPL-3.0-only */ import { useTranslatedText } from '../../../hooks/common/use-translated-text' -import { ShowIf } from '../show-if/show-if' import styles from './user-avatar.module.scss' import React, { useMemo } from 'react' import { useAvatarUrl } from './hooks/use-avatar-url' @@ -64,9 +63,7 @@ export const UserAvatar: React.FC<UserAvatarProps> = ({ height={imageSize} width={imageSize} /> - <ShowIf condition={showName}> - <span className={`ms-2 me-1 ${styles['user-line-name']}`}>{displayName}</span> - </ShowIf> + {showName && <span className={`ms-2 me-1 ${styles['user-line-name']}`}>{displayName}</span>} </span> ) } diff --git a/frontend/src/components/document-read-only-page/document-infobar.tsx b/frontend/src/components/document-read-only-page/document-infobar.tsx index 76d3cafe8..4c96d3919 100644 --- a/frontend/src/components/document-read-only-page/document-infobar.tsx +++ b/frontend/src/components/document-read-only-page/document-infobar.tsx @@ -6,7 +6,6 @@ import { useApplicationState } from '../../hooks/common/use-application-state' import { useTranslatedText } from '../../hooks/common/use-translated-text' import { InternalLink } from '../common/links/internal-link' -import { ShowIf } from '../common/show-if/show-if' import { NoteInfoLineCreatedAt } from '../editor-page/sidebar/specific-sidebar-entries/note-info-sidebar-menu/note-info-line/note-info-line-created-at' import { NoteInfoLineUpdatedBy } from '../editor-page/sidebar/specific-sidebar-entries/note-info-sidebar-menu/note-info-line/note-info-line-updated-by' import styles from './document-infobar.module.scss' @@ -36,15 +35,13 @@ export const DocumentInfobar: React.FC = () => { </div> <span className={'ms-auto'}> {noteDetails.viewCount} <Trans i18nKey={'views.readOnly.viewCount'} /> - <ShowIf condition={true}> - <InternalLink - text={''} - href={`/n/${noteDetails.primaryAddress}`} - icon={IconPencil} - className={'text-primary text-decoration-none mx-1'} - title={linkTitle} - /> - </ShowIf> + <InternalLink + text={''} + href={`/n/${noteDetails.primaryAddress}`} + icon={IconPencil} + className={'text-primary text-decoration-none mx-1'} + title={linkTitle} + /> </span> </div> <div className={'col-md'}> </div> diff --git a/frontend/src/components/editor-page/editor-pane/tool-bar/tool-bar.tsx b/frontend/src/components/editor-page/editor-pane/tool-bar/tool-bar.tsx index 939745c74..b5fd58541 100644 --- a/frontend/src/components/editor-page/editor-pane/tool-bar/tool-bar.tsx +++ b/frontend/src/components/editor-page/editor-pane/tool-bar/tool-bar.tsx @@ -5,7 +5,6 @@ */ import { useMayEdit } from '../../../../hooks/common/use-may-edit' import { concatCssClasses } from '../../../../utils/concat-css-classes' -import { ShowIf } from '../../../common/show-if/show-if' import { BoldButton } from './buttons/bold-button' import { CheckListButton } from './buttons/check-list-button' import { CodeFenceButton } from './buttons/code-fence-button' @@ -38,41 +37,43 @@ const EmojiPickerButton = React.lazy(() => import('./emoji-picker/emoji-picker-b export const ToolBar: React.FC = () => { const mayEdit = useMayEdit() + if (!mayEdit) { + return null + } + return ( - <ShowIf condition={mayEdit}> - <ButtonToolbar className={concatCssClasses(styles.toolbar, 'my-1')}> - <ButtonGroup className={'mx-1 flex-wrap'}> - <BoldButton /> - <ItalicButton /> - <UnderlineButton /> - <StrikethroughButton /> - <SubscriptButton /> - <SuperscriptButton /> - <HighlightButton /> - </ButtonGroup> - <ButtonGroup className={'mx-1 flex-wrap'}> - <HeaderLevelButton /> - <CodeFenceButton /> - <QuotesButton /> - <UnorderedListButton /> - <OrderedListButton /> - <CheckListButton /> - </ButtonGroup> - <ButtonGroup className={'mx-1 flex-wrap'}> - <LinkButton /> - <ImageLinkButton /> - <UploadImageButton /> - </ButtonGroup> - <ButtonGroup className={'mx-1 flex-wrap'}> - <TablePickerButton /> - <HorizontalLineButton /> - <CollapsibleBlockButton /> - <CommentButton /> - <Suspense fallback={<Fragment />}> - <EmojiPickerButton /> - </Suspense> - </ButtonGroup> - </ButtonToolbar> - </ShowIf> + <ButtonToolbar className={concatCssClasses(styles.toolbar, 'my-1')}> + <ButtonGroup className={'mx-1 flex-wrap'}> + <BoldButton /> + <ItalicButton /> + <UnderlineButton /> + <StrikethroughButton /> + <SubscriptButton /> + <SuperscriptButton /> + <HighlightButton /> + </ButtonGroup> + <ButtonGroup className={'mx-1 flex-wrap'}> + <HeaderLevelButton /> + <CodeFenceButton /> + <QuotesButton /> + <UnorderedListButton /> + <OrderedListButton /> + <CheckListButton /> + </ButtonGroup> + <ButtonGroup className={'mx-1 flex-wrap'}> + <LinkButton /> + <ImageLinkButton /> + <UploadImageButton /> + </ButtonGroup> + <ButtonGroup className={'mx-1 flex-wrap'}> + <TablePickerButton /> + <HorizontalLineButton /> + <CollapsibleBlockButton /> + <CommentButton /> + <Suspense fallback={<Fragment />}> + <EmojiPickerButton /> + </Suspense> + </ButtonGroup> + </ButtonToolbar> ) } diff --git a/frontend/src/components/editor-page/editor-pane/tool-bar/upload-image-button/upload-image-button.tsx b/frontend/src/components/editor-page/editor-pane/tool-bar/upload-image-button/upload-image-button.tsx index afe1a4936..d1c752dea 100644 --- a/frontend/src/components/editor-page/editor-pane/tool-bar/upload-image-button/upload-image-button.tsx +++ b/frontend/src/components/editor-page/editor-pane/tool-bar/upload-image-button/upload-image-button.tsx @@ -5,7 +5,6 @@ */ import { cypressId } from '../../../../../utils/cypress-attribute' import { Logger } from '../../../../../utils/logger' -import { ShowIf } from '../../../../common/show-if/show-if' import { acceptedMimeTypes } from '../../../../common/upload-image-mimetypes' import { UploadInput } from '../../../../common/upload-input' import { useCodemirrorReferenceContext } from '../../../change-content-context/codemirror-reference-context' @@ -47,14 +46,14 @@ export const UploadImageButton: React.FC = () => { return ( <Fragment> <ToolbarButton i18nKey={'uploadImage'} icon={IconUpload} onClick={buttonClick}> - <ShowIf condition={!!codeMirror}> + {codeMirror !== undefined && ( <UploadInput onLoad={onUploadImage} allowedFileTypes={acceptedMimeTypes} onClickRef={clickRef} {...cypressId('toolbar.uploadImage.input')} /> - </ShowIf> + )} </ToolbarButton> </Fragment> ) diff --git a/frontend/src/components/editor-page/sidebar/sidebar-button/sidebar-button.tsx b/frontend/src/components/editor-page/sidebar/sidebar-button/sidebar-button.tsx index 5837f7976..bb49f0522 100644 --- a/frontend/src/components/editor-page/sidebar/sidebar-button/sidebar-button.tsx +++ b/frontend/src/components/editor-page/sidebar/sidebar-button/sidebar-button.tsx @@ -5,7 +5,6 @@ */ import { concatCssClasses } from '../../../../utils/concat-css-classes' import { UiIcon } from '../../../common/icons/ui-icon' -import { ShowIf } from '../../../common/show-if/show-if' import type { SidebarEntryProps } from '../types' import styles from './sidebar-button.module.scss' import type { PropsWithChildren } from 'react' @@ -51,11 +50,11 @@ export const SidebarButton: React.FC<PropsWithChildren<SidebarEntryProps>> = ({ className={concatCssClasses(styles.button, className, { [styles.hide]: hide })} disabled={disabled} {...props}> - <ShowIf condition={!!icon}> + {icon !== undefined && ( <span className={`sidebar-button-icon ${styles.icon}`}> <UiIcon icon={icon} /> </span> - </ShowIf> + )} <span className={concatCssClasses(styles.text, { [styles.disabled]: disabled })}>{children}</span> </button> </OverlayTrigger> diff --git a/frontend/src/components/editor-page/sidebar/sidebar-menu-info-entry/sidebar-menu-info-entry.tsx b/frontend/src/components/editor-page/sidebar/sidebar-menu-info-entry/sidebar-menu-info-entry.tsx index f6aef3b04..9d907d736 100644 --- a/frontend/src/components/editor-page/sidebar/sidebar-menu-info-entry/sidebar-menu-info-entry.tsx +++ b/frontend/src/components/editor-page/sidebar/sidebar-menu-info-entry/sidebar-menu-info-entry.tsx @@ -4,7 +4,6 @@ * SPDX-License-Identifier: AGPL-3.0-only */ import { UiIcon } from '../../../common/icons/ui-icon' -import { ShowIf } from '../../../common/show-if/show-if' import styles from './sidebar-menu-info-entry.module.css' import type { PropsWithChildren } from 'react' import React from 'react' @@ -32,9 +31,7 @@ export const SidebarMenuInfoEntry: React.FC<PropsWithChildren<SidebarMenuInfoEnt return ( <div className={`d-flex flex-row align-items-center p-1 ${styles['entry']}`}> - <ShowIf condition={icon !== undefined}> - <UiIcon icon={icon} className={'mx-2'} size={1.25} /> - </ShowIf> + {icon !== undefined && <UiIcon icon={icon} className={'mx-2'} size={1.25} />} <div className={'d-flex flex-column px-1'}> <span className={styles['title']}> <Trans i18nKey={titleI18nKey} /> diff --git a/frontend/src/components/editor-page/sidebar/specific-sidebar-entries/aliases-sidebar-entry/aliases-modal/aliases-list-entry.tsx b/frontend/src/components/editor-page/sidebar/specific-sidebar-entries/aliases-sidebar-entry/aliases-modal/aliases-list-entry.tsx index f093d8557..2702504b1 100644 --- a/frontend/src/components/editor-page/sidebar/specific-sidebar-entries/aliases-sidebar-entry/aliases-modal/aliases-list-entry.tsx +++ b/frontend/src/components/editor-page/sidebar/specific-sidebar-entries/aliases-sidebar-entry/aliases-modal/aliases-list-entry.tsx @@ -10,7 +10,6 @@ import { useTranslatedText } from '../../../../../../hooks/common/use-translated import { updateMetadata } from '../../../../../../redux/note-details/methods' import { testId } from '../../../../../../utils/test-id' import { UiIcon } from '../../../../../common/icons/ui-icon' -import { ShowIf } from '../../../../../common/show-if/show-if' import { useUiNotifications } from '../../../../../notifications/ui-notification-boundary' import React, { useCallback } from 'react' import { Button } from 'react-bootstrap' @@ -51,7 +50,7 @@ export const AliasesListEntry: React.FC<AliasesListEntryProps> = ({ alias }) => <li className={'list-group-item d-flex flex-row justify-content-between align-items-center'}> {alias.name} <div> - <ShowIf condition={alias.primaryAlias}> + {alias.primaryAlias && ( <Button className={'me-2 text-warning'} variant='light' @@ -60,8 +59,8 @@ export const AliasesListEntry: React.FC<AliasesListEntryProps> = ({ alias }) => {...testId('aliasIsPrimary')}> <UiIcon icon={IconStar} /> </Button> - </ShowIf> - <ShowIf condition={!alias.primaryAlias}> + )} + {!alias.primaryAlias && ( <Button className={'me-2'} variant='light' @@ -71,7 +70,7 @@ export const AliasesListEntry: React.FC<AliasesListEntryProps> = ({ alias }) => {...testId('aliasButtonMakePrimary')}> <UiIcon icon={IconStarFill} /> </Button> - </ShowIf> + )} <Button variant='light' className={'text-danger'} diff --git a/frontend/src/components/editor-page/sidebar/specific-sidebar-entries/import-markdown-sidebar-entry.tsx b/frontend/src/components/editor-page/sidebar/specific-sidebar-entries/import-markdown-sidebar-entry.tsx index da136afd0..4a24fb0a2 100644 --- a/frontend/src/components/editor-page/sidebar/specific-sidebar-entries/import-markdown-sidebar-entry.tsx +++ b/frontend/src/components/editor-page/sidebar/specific-sidebar-entries/import-markdown-sidebar-entry.tsx @@ -5,7 +5,6 @@ */ import { cypressId } from '../../../../utils/cypress-attribute' import { FileContentFormat, readFile } from '../../../../utils/read-file' -import { ShowIf } from '../../../common/show-if/show-if' import { UploadInput } from '../../../common/upload-input' import { useChangeEditorContentCallback } from '../../change-content-context/use-change-editor-content-callback' import { SidebarButton } from '../sidebar-button/sidebar-button' @@ -54,14 +53,14 @@ export const ImportMarkdownSidebarEntry: React.FC = () => { disabled={!changeEditorContent}> <Trans i18nKey={'editor.import.file'} /> </SidebarButton> - <ShowIf condition={!!changeEditorContent}> + {changeEditorContent !== undefined && ( <UploadInput onLoad={onImportMarkdown} {...cypressId('menu-import-markdown-input')} allowedFileTypes={'.md, text/markdown, text/plain'} onClickRef={clickRef} /> - </ShowIf> + )} </Fragment> ) } diff --git a/frontend/src/components/editor-page/sidebar/specific-sidebar-entries/note-info-sidebar-menu/note-info-line/note-info-line-word-count.tsx b/frontend/src/components/editor-page/sidebar/specific-sidebar-entries/note-info-sidebar-menu/note-info-line/note-info-line-word-count.tsx index dea111f9e..8e9781c43 100644 --- a/frontend/src/components/editor-page/sidebar/specific-sidebar-entries/note-info-sidebar-menu/note-info-line/note-info-line-word-count.tsx +++ b/frontend/src/components/editor-page/sidebar/specific-sidebar-entries/note-info-sidebar-menu/note-info-line/note-info-line-word-count.tsx @@ -5,7 +5,6 @@ */ import { useApplicationState } from '../../../../../../hooks/common/use-application-state' import { cypressId } from '../../../../../../utils/cypress-attribute' -import { ShowIf } from '../../../../../common/show-if/show-if' import { useEditorReceiveHandler } from '../../../../../render-page/window-post-message-communicator/hooks/use-editor-receive-handler' import type { OnWordCountCalculatedMessage } from '../../../../../render-page/window-post-message-communicator/rendering-message' import { CommunicationMessageType } from '../../../../../render-page/window-post-message-communicator/rendering-message' @@ -42,12 +41,8 @@ export const NoteInfoLineWordCount: React.FC<NoteInfoLineWordCountProps> = ({ vi return ( <SidebarMenuInfoEntry titleI18nKey={'editor.noteInfo.wordCount'} icon={IconAlignStart}> - <ShowIf condition={wordCount === null}> - <Trans i18nKey={'common.loading'} /> - </ShowIf> - <ShowIf condition={wordCount !== null}> - <span {...cypressId('document-info-word-count')}>{wordCount}</span> - </ShowIf> + {wordCount === null && <Trans i18nKey={'common.loading'} />} + {wordCount !== null && <span {...cypressId('document-info-word-count')}>{wordCount}</span>} </SidebarMenuInfoEntry> ) } diff --git a/frontend/src/components/editor-page/sidebar/specific-sidebar-entries/permissions-sidebar-entry/permissions-modal/permission-entry-user.tsx b/frontend/src/components/editor-page/sidebar/specific-sidebar-entries/permissions-sidebar-entry/permissions-modal/permission-entry-user.tsx index f960a014b..ef7b6d640 100644 --- a/frontend/src/components/editor-page/sidebar/specific-sidebar-entries/permissions-sidebar-entry/permissions-modal/permission-entry-user.tsx +++ b/frontend/src/components/editor-page/sidebar/specific-sidebar-entries/permissions-sidebar-entry/permissions-modal/permission-entry-user.tsx @@ -7,7 +7,6 @@ import { removeUserPermission, setUserPermission } from '../../../../../../api/p import { getUser } from '../../../../../../api/users' import { useApplicationState } from '../../../../../../hooks/common/use-application-state' import { setNotePermissionsFromServer } from '../../../../../../redux/note-details/methods' -import { ShowIf } from '../../../../../common/show-if/show-if' import { UserAvatarForUser } from '../../../../../common/user-avatar/user-avatar-for-user' import { useUiNotifications } from '../../../../../notifications/ui-notification-boundary' import type { PermissionDisabledProps } from './permission-disabled.prop' @@ -18,6 +17,7 @@ import React, { useCallback, useMemo } from 'react' import { useAsync } from 'react-use' import { PermissionInconsistentAlert } from './permission-inconsistent-alert' import { useGetSpecialPermissions } from './hooks/use-get-special-permissions' +import { AsyncLoadingBoundary } from '../../../../../common/async-loading-boundary/async-loading-boundary' export interface PermissionEntryUserProps { entry: NoteUserPermissionEntry @@ -87,7 +87,7 @@ export const PermissionEntryUser: React.FC<PermissionEntryUserProps & Permission } return ( - <ShowIf condition={!loading && !error}> + <AsyncLoadingBoundary loading={loading} error={error} componentName={'PermissionEntryUser'}> <li className={'list-group-item d-flex flex-row justify-content-between align-items-center'}> <UserAvatarForUser user={value} /> <div className={'d-flex flex-row align-items-center'}> @@ -103,6 +103,6 @@ export const PermissionEntryUser: React.FC<PermissionEntryUserProps & Permission /> </div> </li> - </ShowIf> + </AsyncLoadingBoundary> ) } diff --git a/frontend/src/components/editor-page/sidebar/specific-sidebar-entries/revisions-sidebar-entry/revisions-modal/revision-list-entry.tsx b/frontend/src/components/editor-page/sidebar/specific-sidebar-entries/revisions-sidebar-entry/revisions-modal/revision-list-entry.tsx index 468ebbb01..699554f2d 100644 --- a/frontend/src/components/editor-page/sidebar/specific-sidebar-entries/revisions-sidebar-entry/revisions-modal/revision-list-entry.tsx +++ b/frontend/src/components/editor-page/sidebar/specific-sidebar-entries/revisions-sidebar-entry/revisions-modal/revision-list-entry.tsx @@ -5,7 +5,6 @@ */ import type { RevisionMetadata } from '../../../../../../api/revisions/types' import { UiIcon } from '../../../../../common/icons/ui-icon' -import { ShowIf } from '../../../../../common/show-if/show-if' import { UserAvatarForUser } from '../../../../../common/user-avatar/user-avatar-for-user' import { WaitSpinner } from '../../../../../common/wait-spinner/wait-spinner' import { useUiNotifications } from '../../../../../notifications/ui-notification-boundary' @@ -72,10 +71,8 @@ export const RevisionListEntry: React.FC<RevisionListEntryProps> = ({ active, on </span> <span className={'d-flex flex-row my-1 align-items-center'}> <UiIcon icon={IconPerson} className={'mx-2'} /> - <ShowIf condition={revisionAuthors.loading}> - <WaitSpinner /> - </ShowIf> - <ShowIf condition={!revisionAuthors.error && !revisionAuthors.loading}>{revisionAuthors.value}</ShowIf> + {revisionAuthors.loading && <WaitSpinner />} + {!revisionAuthors.error && !revisionAuthors.loading && revisionAuthors.value} </span> <span> <UiIcon icon={IconPersonPlus} className='mx-2' /> diff --git a/frontend/src/components/editor-page/sidebar/specific-sidebar-entries/share-note-sidebar-entry/share-modal/share-modal.tsx b/frontend/src/components/editor-page/sidebar/specific-sidebar-entries/share-note-sidebar-entry/share-modal/share-modal.tsx index 248a83382..3ed1f2d99 100644 --- a/frontend/src/components/editor-page/sidebar/specific-sidebar-entries/share-note-sidebar-entry/share-modal/share-modal.tsx +++ b/frontend/src/components/editor-page/sidebar/specific-sidebar-entries/share-note-sidebar-entry/share-modal/share-modal.tsx @@ -6,7 +6,6 @@ import { useApplicationState } from '../../../../../../hooks/common/use-application-state' import type { ModalVisibilityProps } from '../../../../../common/modals/common-modal' import { CommonModal } from '../../../../../common/modals/common-modal' -import { ShowIf } from '../../../../../common/show-if/show-if' import { LinkType, NoteUrlField } from './note-url-field' import { NoteType } from '@hedgedoc/commons' import React from 'react' @@ -32,14 +31,18 @@ export const ShareModal: React.FC<ModalVisibilityProps> = ({ show, onHide }) => <Modal.Body> <Trans i18nKey={'editor.modal.shareLink.editorDescription'} /> <NoteUrlField type={LinkType.EDITOR} /> - <ShowIf condition={noteFrontmatter.type === NoteType.SLIDE}> - <Trans i18nKey={'editor.modal.shareLink.slidesDescription'} /> - <NoteUrlField type={LinkType.SLIDESHOW} /> - </ShowIf> - <ShowIf condition={noteFrontmatter.type === NoteType.DOCUMENT}> - <Trans i18nKey={'editor.modal.shareLink.viewOnlyDescription'} /> - <NoteUrlField type={LinkType.DOCUMENT} /> - </ShowIf> + {noteFrontmatter.type === NoteType.SLIDE && ( + <> + <Trans i18nKey={'editor.modal.shareLink.slidesDescription'} /> + <NoteUrlField type={LinkType.SLIDESHOW} /> + </> + )} + {noteFrontmatter.type === NoteType.DOCUMENT && ( + <> + <Trans i18nKey={'editor.modal.shareLink.viewOnlyDescription'} /> + <NoteUrlField type={LinkType.DOCUMENT} /> + </> + )} </Modal.Body> </CommonModal> ) diff --git a/frontend/src/components/editor-page/sidebar/specific-sidebar-entries/users-online-sidebar-menu/user-line/user-line.tsx b/frontend/src/components/editor-page/sidebar/specific-sidebar-entries/users-online-sidebar-menu/user-line/user-line.tsx index 29340dcfd..e06a67576 100644 --- a/frontend/src/components/editor-page/sidebar/specific-sidebar-entries/users-online-sidebar-menu/user-line/user-line.tsx +++ b/frontend/src/components/editor-page/sidebar/specific-sidebar-entries/users-online-sidebar-menu/user-line/user-line.tsx @@ -10,7 +10,6 @@ import { ActiveIndicator } from '../active-indicator' import styles from './user-line.module.scss' import React, { useMemo } from 'react' import { Trans, useTranslation } from 'react-i18next' -import { ShowIf } from '../../../../../common/show-if/show-if' import { Incognito as IconIncognito } from 'react-bootstrap-icons' import { useTranslatedText } from '../../../../../../hooks/common/use-translated-text' @@ -48,9 +47,7 @@ export const UserLine: React.FC<UserLineProps> = ({ username, displayName, activ <div className={`${styles['user-line-color-indicator']} ${createCursorCssClass(color)}`} /> {avatar} <div className={'ms-auto d-flex align-items-center gap-1 h-100'}> - <ShowIf condition={!username}> - <IconIncognito title={guestUserTitle} size={'16px'} className={'text-muted'} /> - </ShowIf> + {!username && <IconIncognito title={guestUserTitle} size={'16px'} className={'text-muted'} />} {own ? ( <span className={'px-1'}> <Trans i18nKey={'editor.onlineStatus.you'}></Trans> diff --git a/frontend/src/components/editor-page/splitter/splitter.tsx b/frontend/src/components/editor-page/splitter/splitter.tsx index 7469af408..5dbda2173 100644 --- a/frontend/src/components/editor-page/splitter/splitter.tsx +++ b/frontend/src/components/editor-page/splitter/splitter.tsx @@ -1,9 +1,8 @@ /* - * SPDX-FileCopyrightText: 2022 The HedgeDoc developers (see AUTHORS file) + * SPDX-FileCopyrightText: 2023 The HedgeDoc developers (see AUTHORS file) * * SPDX-License-Identifier: AGPL-3.0-only */ -import { ShowIf } from '../../common/show-if/show-if' import { useKeyboardShortcuts } from './hooks/use-keyboard-shortcuts' import { DividerButtonsShift, SplitDivider } from './split-divider/split-divider' import styles from './splitter.module.scss' @@ -140,7 +139,7 @@ export const Splitter: React.FC<SplitterProps> = ({ additionalContainerClassName className={`flex-fill flex-row d-flex ${additionalContainerClassName || ''}${ resizingInProgress ? ' ' + styles.resizing : '' }`}> - <ShowIf condition={resizingInProgress}> + {resizingInProgress && ( <div className={styles['move-overlay']} onTouchMove={onMove} @@ -148,7 +147,7 @@ export const Splitter: React.FC<SplitterProps> = ({ additionalContainerClassName onTouchCancel={onStopResizing} onTouchEnd={onStopResizing} onMouseUp={onStopResizing}></div> - </ShowIf> + )} <div className={styles['left']} style={{ width: `calc(${adjustedRelativeSplitValue}% - 5px)` }}> <div className={styles['inner']}>{left}</div> </div> diff --git a/frontend/src/components/editor-page/table-of-contents/table-of-contents.tsx b/frontend/src/components/editor-page/table-of-contents/table-of-contents.tsx index 3005bc4bb..d1d285037 100644 --- a/frontend/src/components/editor-page/table-of-contents/table-of-contents.tsx +++ b/frontend/src/components/editor-page/table-of-contents/table-of-contents.tsx @@ -1,10 +1,9 @@ /* - * SPDX-FileCopyrightText: 2022 The HedgeDoc developers (see AUTHORS file) + * SPDX-FileCopyrightText: 2023 The HedgeDoc developers (see AUTHORS file) * * SPDX-License-Identifier: AGPL-3.0-only */ import { concatCssClasses } from '../../../utils/concat-css-classes' -import { ShowIf } from '../../common/show-if/show-if' import styles from './table-of-contents.module.scss' import { useBuildReactDomFromTocAst } from './use-build-react-dom-from-toc-ast' import type { TocAst } from '@hedgedoc/markdown-it-plugins' @@ -32,9 +31,7 @@ export const TableOfContents: React.FC<TableOfContentsProps> = ({ ast, maxDepth return ( <div className={concatCssClasses(styles.toc, className)}> - <ShowIf condition={ast.children.length === 0}> - <Trans i18nKey={'editor.infoToc'} /> - </ShowIf> + {ast.children.length === 0 && <Trans i18nKey={'editor.infoToc'} />} {tocTree} </div> ) diff --git a/frontend/src/components/editor-page/table-of-contents/use-build-react-dom-from-toc-ast.tsx b/frontend/src/components/editor-page/table-of-contents/use-build-react-dom-from-toc-ast.tsx index f9bc821b8..5c7e854d0 100644 --- a/frontend/src/components/editor-page/table-of-contents/use-build-react-dom-from-toc-ast.tsx +++ b/frontend/src/components/editor-page/table-of-contents/use-build-react-dom-from-toc-ast.tsx @@ -1,9 +1,8 @@ /* - * SPDX-FileCopyrightText: 2022 The HedgeDoc developers (see AUTHORS file) + * SPDX-FileCopyrightText: 2023 The HedgeDoc developers (see AUTHORS file) * * SPDX-License-Identifier: AGPL-3.0-only */ -import { ShowIf } from '../../common/show-if/show-if' import { JumpAnchor } from '../../markdown-renderer/extensions/link-replacer/jump-anchor' import { tocSlugify } from './toc-slugify' import type { TocAst } from '@hedgedoc/markdown-it-plugins' @@ -42,14 +41,12 @@ const buildReactDomFromTocAst = ( return ( <Fragment> - <ShowIf condition={toc.level > 0}> + {toc.level > 0 && ( <JumpAnchor href={headlineUrl} title={rawName} jumpTargetId={slug.slice(1)}> {rawName} </JumpAnchor> - </ShowIf> - <ShowIf condition={children.length > 0}> - <ul>{children}</ul> - </ShowIf> + )} + {children.length > 0 && <ul>{children}</ul>} </Fragment> ) } diff --git a/frontend/src/components/error-pages/common-error-page.tsx b/frontend/src/components/error-pages/common-error-page.tsx index 69711b726..8dbdf19af 100644 --- a/frontend/src/components/error-pages/common-error-page.tsx +++ b/frontend/src/components/error-pages/common-error-page.tsx @@ -4,7 +4,6 @@ * * SPDX-License-Identifier: AGPL-3.0-only */ -import { ShowIf } from '../common/show-if/show-if' import { LandingLayout } from '../landing-layout/landing-layout' import type { PropsWithChildren } from 'react' import React from 'react' @@ -35,11 +34,11 @@ export const CommonErrorPage: React.FC<PropsWithChildren<CommonErrorPageProps>> <h1> <Trans i18nKey={titleI18nKey} /> </h1> - <ShowIf condition={!!descriptionI18nKey}> + {descriptionI18nKey !== undefined && ( <h3> <Trans i18nKey={descriptionI18nKey} /> </h3> - </ShowIf> + )} {children} </div> </LandingLayout> diff --git a/frontend/src/components/global-dialogs/shortcuts-modal/shortcut-line.tsx b/frontend/src/components/global-dialogs/shortcuts-modal/shortcut-line.tsx index 3ae02c853..ebdb7526f 100644 --- a/frontend/src/components/global-dialogs/shortcuts-modal/shortcut-line.tsx +++ b/frontend/src/components/global-dialogs/shortcuts-modal/shortcut-line.tsx @@ -3,7 +3,6 @@ * * SPDX-License-Identifier: AGPL-3.0-only */ -import { ShowIf } from '../../common/show-if/show-if' import { AltKey } from './alt-key' import { ModifierKey } from './modifier-key' import React from 'react' @@ -39,15 +38,19 @@ export const ShortcutLine: React.FC<ShortcutLineProps> = ({ <Trans i18nKey={functionNameI18nKey} /> </span> <span> - <ShowIf condition={showModifierKey}> - <ModifierKey /> - <span> + </span> - </ShowIf> + {showModifierKey && ( + <> + <ModifierKey /> + <span> + </span> + </> + )} - <ShowIf condition={showAltKey}> - <AltKey /> - <span> + </span> - </ShowIf> + {showAltKey && ( + <> + <AltKey /> + <span> + </span> + </> + )} <kbd>{functionKeyCode.toUpperCase()}</kbd> </span> diff --git a/frontend/src/components/global-dialogs/version-info-modal/version-info-modal.tsx b/frontend/src/components/global-dialogs/version-info-modal/version-info-modal.tsx index 56611b440..e179673b8 100644 --- a/frontend/src/components/global-dialogs/version-info-modal/version-info-modal.tsx +++ b/frontend/src/components/global-dialogs/version-info-modal/version-info-modal.tsx @@ -11,7 +11,6 @@ import { useFrontendConfig } from '../../common/frontend-config-context/use-fron import { TranslatedExternalLink } from '../../common/links/translated-external-link' import type { CommonModalProps } from '../../common/modals/common-modal' import { CommonModal } from '../../common/modals/common-modal' -import { ShowIf } from '../../common/show-if/show-if' import React, { useMemo } from 'react' import { Modal } from 'react-bootstrap' @@ -46,20 +45,20 @@ export const VersionInfoModal: React.FC<CommonModalProps> = ({ onHide, show }) = <Modal.Body> <CopyableField content={backendVersion} /> <div className='d-flex justify-content-between mt-3'> - <ShowIf condition={!!links.sourceCode}> + {links.sourceCode !== undefined && ( <TranslatedExternalLink i18nKey={'landing.versionInfo.sourceCode'} className={'btn btn-primary d-block mb-2'} href={links.sourceCode} /> - </ShowIf> - <ShowIf condition={!!links.issues}> + )} + {links.issues !== undefined && ( <TranslatedExternalLink i18nKey={'landing.versionInfo.issueTracker'} className={'btn btn-primary d-block mb-2'} href={links.issues} /> - </ShowIf> + )} </div> </Modal.Body> </CommonModal> diff --git a/frontend/src/components/history-page/entry-menu/entry-menu.tsx b/frontend/src/components/history-page/entry-menu/entry-menu.tsx index 6b7c62275..f591e3f2a 100644 --- a/frontend/src/components/history-page/entry-menu/entry-menu.tsx +++ b/frontend/src/components/history-page/entry-menu/entry-menu.tsx @@ -6,7 +6,6 @@ import { HistoryEntryOrigin } from '../../../api/history/types' import { cypressId } from '../../../utils/cypress-attribute' import { UiIcon } from '../../common/icons/ui-icon' -import { ShowIf } from '../../common/show-if/show-if' import { DeleteNoteItem } from './delete-note-item' import styles from './entry-menu.module.scss' import { RemoveNoteEntryItem } from './remove-note-entry-item' @@ -60,27 +59,29 @@ export const EntryMenu: React.FC<EntryMenuProps> = ({ <Trans i18nKey='landing.history.menu.recentNotes' /> </Dropdown.Header> - <ShowIf condition={origin === HistoryEntryOrigin.LOCAL}> + {origin === HistoryEntryOrigin.LOCAL && ( <Dropdown.Item disabled> <UiIcon icon={IconLaptop} className='mx-2' /> <Trans i18nKey='landing.history.menu.entryLocal' /> </Dropdown.Item> - </ShowIf> + )} - <ShowIf condition={origin === HistoryEntryOrigin.REMOTE}> + {origin === HistoryEntryOrigin.REMOTE && ( <Dropdown.Item disabled> <UiIcon icon={IconCloud} className='mx-2' /> <Trans i18nKey='landing.history.menu.entryRemote' /> </Dropdown.Item> - </ShowIf> + )} <RemoveNoteEntryItem onConfirm={onRemoveFromHistory} noteTitle={title} /> {/* TODO Check permissions (ownership) before showing option for delete (https://github.com/hedgedoc/hedgedoc/issues/5036)*/} - <ShowIf condition={userExists}> - <Dropdown.Divider /> - <DeleteNoteItem onConfirm={onDeleteNote} noteTitle={title} /> - </ShowIf> + {userExists && ( + <> + <Dropdown.Divider /> + <DeleteNoteItem onConfirm={onDeleteNote} noteTitle={title} /> + </> + )} </Dropdown.Menu> </Dropdown> ) diff --git a/frontend/src/components/history-page/history-toolbar/history-toolbar.tsx b/frontend/src/components/history-page/history-toolbar/history-toolbar.tsx index fef41f802..aea54fa37 100644 --- a/frontend/src/components/history-page/history-toolbar/history-toolbar.tsx +++ b/frontend/src/components/history-page/history-toolbar/history-toolbar.tsx @@ -8,7 +8,6 @@ import { useApplicationState } from '../../../hooks/common/use-application-state import { useTranslatedText } from '../../../hooks/common/use-translated-text' import { importHistoryEntries, setHistoryEntries } from '../../../redux/history/methods' import { UiIcon } from '../../common/icons/ui-icon' -import { ShowIf } from '../../common/show-if/show-if' import { useUiNotifications } from '../../notifications/ui-notification-boundary' import { ClearHistoryButton } from './clear-history-button' import { ExportHistoryButton } from './export-history-button' @@ -89,13 +88,13 @@ export const HistoryToolbar: React.FC = () => { <div className={'me-1 mb-1'}> <HistoryRefreshButton /> </div> - <ShowIf condition={userExists}> + {userExists && ( <div className={'me-1 mb-1'}> <Button variant={'secondary'} title={uploadAllButtonTitle} onClick={onUploadAllToRemote}> <UiIcon icon={IconCloudUpload} /> </Button> </div> - </ShowIf> + )} <div className={'me-1 mb-1'}> <HistoryViewModeToggleButton /> </div> diff --git a/frontend/src/components/intro-page/intro-custom-content.tsx b/frontend/src/components/intro-page/intro-custom-content.tsx index 13229b674..3de0c4fa6 100644 --- a/frontend/src/components/intro-page/intro-custom-content.tsx +++ b/frontend/src/components/intro-page/intro-custom-content.tsx @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2021 The HedgeDoc developers (see AUTHORS file) + * SPDX-FileCopyrightText: 2023 The HedgeDoc developers (see AUTHORS file) * * SPDX-License-Identifier: AGPL-3.0-only */ @@ -29,7 +29,7 @@ export const IntroCustomContent: React.FC = () => { <AsyncLoadingBoundary loading={loading || !value} error={error} componentName={'custom intro content'}> <RendererIframe frameClasses={'w-100 overflow-y-hidden'} - markdownContentLines={value as string[]} + markdownContentLines={value ?? []} rendererType={RendererType.SIMPLE} adaptFrameHeightToContent={true} showWaitSpinner={true} diff --git a/frontend/src/components/landing-layout/navigation/sign-in-button.tsx b/frontend/src/components/landing-layout/navigation/sign-in-button.tsx index e76f5be12..4d59c541d 100644 --- a/frontend/src/components/landing-layout/navigation/sign-in-button.tsx +++ b/frontend/src/components/landing-layout/navigation/sign-in-button.tsx @@ -6,7 +6,6 @@ import { useTranslatedText } from '../../../hooks/common/use-translated-text' import { cypressId } from '../../../utils/cypress-attribute' import { useFrontendConfig } from '../../common/frontend-config-context/use-frontend-config' -import { ShowIf } from '../../common/show-if/show-if' import Link from 'next/link' import React, { useMemo } from 'react' import { Button } from 'react-bootstrap' @@ -39,13 +38,15 @@ export const SignInButton: React.FC<SignInButtonProps> = ({ variant, ...props }) }, [authProviders, pathname]) const buttonTitle = useTranslatedText('login.signIn') + if (authProviders.length === 0) { + return null + } + return ( - <ShowIf condition={authProviders.length > 0}> - <Link href={loginLink} passHref={true}> - <Button title={buttonTitle} {...cypressId('sign-in-button')} variant={variant || 'success'} {...props}> - <Trans i18nKey='login.signIn' /> - </Button> - </Link> - </ShowIf> + <Link href={loginLink} passHref={true}> + <Button title={buttonTitle} {...cypressId('sign-in-button')} variant={variant || 'success'} {...props}> + <Trans i18nKey='login.signIn' /> + </Button> + </Link> ) } diff --git a/frontend/src/components/layout/app-bar/app-bar-elements/help-dropdown/submenues/legal-submenu.tsx b/frontend/src/components/layout/app-bar/app-bar-elements/help-dropdown/submenues/legal-submenu.tsx index b9ee33b8b..ef1984e58 100644 --- a/frontend/src/components/layout/app-bar/app-bar-elements/help-dropdown/submenues/legal-submenu.tsx +++ b/frontend/src/components/layout/app-bar/app-bar-elements/help-dropdown/submenues/legal-submenu.tsx @@ -3,7 +3,6 @@ * * SPDX-License-Identifier: AGPL-3.0-only */ -import { ShowIf } from '../../../../../common/show-if/show-if' import { DropdownHeader } from '../dropdown-header' import { TranslatedDropdownItem } from '../translated-dropdown-item' import type { ReactElement } from 'react' @@ -29,15 +28,15 @@ export const LegalSubmenu: React.FC = (): null | ReactElement => { <Fragment> <Dropdown.Divider /> <DropdownHeader i18nKey={'appbar.help.legal.header'} /> - <ShowIf condition={!!specialUrls.privacy}> + {specialUrls.privacy !== undefined && ( <TranslatedDropdownItem href={specialUrls.privacy} i18nKey={'appbar.help.legal.privacy'} /> - </ShowIf> - <ShowIf condition={!!specialUrls.termsOfUse}> + )} + {specialUrls.termsOfUse !== undefined && ( <TranslatedDropdownItem href={specialUrls.termsOfUse} i18nKey={'appbar.help.legal.termsOfUse'} /> - </ShowIf> - <ShowIf condition={!!specialUrls.imprint}> + )} + {specialUrls.imprint !== undefined && ( <TranslatedDropdownItem href={specialUrls.imprint} i18nKey={'appbar.help.legal.imprint'} /> - </ShowIf> + )} </Fragment> ) } diff --git a/frontend/src/components/layout/app-bar/app-bar-elements/help-dropdown/translated-dropdown-item.tsx b/frontend/src/components/layout/app-bar/app-bar-elements/help-dropdown/translated-dropdown-item.tsx index fdf0e26ec..c04d8b715 100644 --- a/frontend/src/components/layout/app-bar/app-bar-elements/help-dropdown/translated-dropdown-item.tsx +++ b/frontend/src/components/layout/app-bar/app-bar-elements/help-dropdown/translated-dropdown-item.tsx @@ -5,7 +5,6 @@ */ import { useTranslatedText } from '../../../../../hooks/common/use-translated-text' import { UiIcon } from '../../../../common/icons/ui-icon' -import { ShowIf } from '../../../../common/show-if/show-if' import type { TOptions } from 'i18next' import React from 'react' import { Dropdown } from 'react-bootstrap' @@ -36,9 +35,7 @@ export const TranslatedDropdownItem: React.FC<TranslatedDropdownItemProps> = ({ return ( <Dropdown.Item {...props} title={title} className={'d-flex align-items-center'}> - <ShowIf condition={!!icon}> - <UiIcon icon={icon} className={'me-2'} /> - </ShowIf> + {icon !== undefined && <UiIcon icon={icon} className={'me-2'} />} <span>{title}</span> </Dropdown.Item> ) diff --git a/frontend/src/components/layout/app-bar/app-bar-elements/note-title-element/note-title-element.tsx b/frontend/src/components/layout/app-bar/app-bar-elements/note-title-element/note-title-element.tsx index 38f224986..526f1f5d6 100644 --- a/frontend/src/components/layout/app-bar/app-bar-elements/note-title-element/note-title-element.tsx +++ b/frontend/src/components/layout/app-bar/app-bar-elements/note-title-element/note-title-element.tsx @@ -9,7 +9,6 @@ import { useMayEdit } from '../../../../../hooks/common/use-may-edit' import { useNoteTitle } from '../../../../../hooks/common/use-note-title' import { useTranslatedText } from '../../../../../hooks/common/use-translated-text' import { UiIcon } from '../../../../common/icons/ui-icon' -import { ShowIf } from '../../../../common/show-if/show-if' import React from 'react' import { Lock as IconLock } from 'react-bootstrap-icons' @@ -23,11 +22,11 @@ export const NoteTitleElement: React.FC = () => { return ( <span className={'m-0 text-truncate'}> - <ShowIf condition={!isWriteable}> + {!isWriteable && ( <span className={'text-secondary me-2'}> <UiIcon icon={IconLock} className={'me-2'} title={readOnlyLabel} /> </span> - </ShowIf> + )} {noteTitle} </span> ) diff --git a/frontend/src/components/login-page/guest/guest-card.tsx b/frontend/src/components/login-page/guest/guest-card.tsx index b98330350..2ca30d3bc 100644 --- a/frontend/src/components/login-page/guest/guest-card.tsx +++ b/frontend/src/components/login-page/guest/guest-card.tsx @@ -11,7 +11,6 @@ import { HistoryButton } from '../../layout/app-bar/app-bar-elements/help-dropdo import { useFrontendConfig } from '../../common/frontend-config-context/use-frontend-config' import { Trans, useTranslation } from 'react-i18next' import { GuestAccessLevel } from '../../../api/config/types' -import { ShowIf } from '../../common/show-if/show-if' /** * Renders the card with the options for not logged-in users. @@ -35,11 +34,11 @@ export const GuestCard: React.FC = () => { <NewNoteButton /> <HistoryButton /> </div> - <ShowIf condition={guestAccessLevel !== GuestAccessLevel.CREATE}> + {guestAccessLevel !== GuestAccessLevel.CREATE && ( <div className={'text-muted mt-2 small'}> <Trans i18nKey={'login.guest.noteCreationDisabled'} /> </div> - </ShowIf> + )} </Card.Body> </Card> ) diff --git a/frontend/src/components/login-page/local-login/local-login-card.tsx b/frontend/src/components/login-page/local-login/local-login-card.tsx index 0f6e03353..fb54c8066 100644 --- a/frontend/src/components/login-page/local-login/local-login-card.tsx +++ b/frontend/src/components/login-page/local-login/local-login-card.tsx @@ -10,7 +10,6 @@ import { useFrontendConfig } from '../../common/frontend-config-context/use-fron import { AuthProviderType } from '../../../api/config/types' import { LocalLoginCardBody } from './local-login-card-body' import { LocalRegisterCardBody } from './register/local-register-card-body' -import { ShowIf } from '../../common/show-if/show-if' /** * Shows the card that processes local logins and registers. @@ -29,10 +28,12 @@ export const LocalLoginCard: React.FC = () => { return ( <Card> <LocalLoginCardBody /> - <ShowIf condition={frontendConfig.allowRegister}> - <hr className={'m-0'} /> - <LocalRegisterCardBody /> - </ShowIf> + {frontendConfig.allowRegister && ( + <> + <hr className={'m-0'} /> + <LocalRegisterCardBody /> + </> + )} </Card> ) } diff --git a/frontend/src/components/markdown-renderer/replace-components/click-shield/click-shield.tsx b/frontend/src/components/markdown-renderer/replace-components/click-shield/click-shield.tsx index 92bddd98a..37755daf3 100644 --- a/frontend/src/components/markdown-renderer/replace-components/click-shield/click-shield.tsx +++ b/frontend/src/components/markdown-renderer/replace-components/click-shield/click-shield.tsx @@ -1,12 +1,11 @@ /* - * SPDX-FileCopyrightText: 2022 The HedgeDoc developers (see AUTHORS file) + * SPDX-FileCopyrightText: 2023 The HedgeDoc developers (see AUTHORS file) * * SPDX-License-Identifier: AGPL-3.0-only */ import type { PropsWithDataCypressId } from '../../../../utils/cypress-attribute' import { cypressId } from '../../../../utils/cypress-attribute' import { Logger } from '../../../../utils/logger' -import { ShowIf } from '../../../common/show-if/show-if' import { ProxyImageFrame } from '../../extensions/image/proxy-image-frame' import styles from './click-shield.module.scss' import type { Property } from 'csstype' @@ -113,20 +112,25 @@ export const ClickShield: React.FC<ClickShieldProps> = ({ [hoverIcon] ) + if (showChildren) { + return ( + <span className={containerClassName} {...cypressId(props['data-cypress-id'])}> + {children} + </span> + ) + } + return ( <span className={containerClassName} {...cypressId(props['data-cypress-id'])}> - <ShowIf condition={showChildren}>{children}</ShowIf> - <ShowIf condition={!showChildren}> - <span className={`${styles['click-shield']} d-inline-block ratio ratio-16x9`} onClick={doShowChildren}> - {previewBackground} - <span className={`${styles['preview-hover']}`}> - <span> - <Trans i18nKey={'renderer.clickShield.previewHoverText'} values={hoverTextTranslationValues} /> - </span> - {icon} + <span className={`${styles['click-shield']} d-inline-block ratio ratio-16x9`} onClick={doShowChildren}> + {previewBackground} + <span className={`${styles['preview-hover']}`}> + <span> + <Trans i18nKey={'renderer.clickShield.previewHoverText'} values={hoverTextTranslationValues} /> </span> + {icon} </span> - </ShowIf> + </span> </span> ) } diff --git a/frontend/src/components/notifications/ui-notification-toast.tsx b/frontend/src/components/notifications/ui-notification-toast.tsx index 13198438c..9d52c9b53 100644 --- a/frontend/src/components/notifications/ui-notification-toast.tsx +++ b/frontend/src/components/notifications/ui-notification-toast.tsx @@ -6,7 +6,6 @@ import { cypressId } from '../../utils/cypress-attribute' import { Logger } from '../../utils/logger' import { UiIcon } from '../common/icons/ui-icon' -import { ShowIf } from '../common/show-if/show-if' import styles from './notifications.module.scss' import type { UiNotification } from './types' import { useUiNotifications } from './ui-notification-boundary' @@ -106,9 +105,7 @@ export const UiNotificationToast: React.FC<UiNotificationProps> = ({ notificatio {...cypressId('notification-toast')}> <Toast.Header> <strong className='me-auto'> - <ShowIf condition={!!notification.icon}> - <UiIcon icon={notification.icon} className={'me-1'} /> - </ShowIf> + {notification.icon !== undefined && <UiIcon icon={notification.icon} className={'me-1'} />} <Trans i18nKey={notification.titleI18nKey} tOptions={notification.titleI18nOptions} /> </strong> <small>{formattedCreatedAtDate}</small> diff --git a/frontend/src/components/profile-page/access-tokens/profile-access-tokens.tsx b/frontend/src/components/profile-page/access-tokens/profile-access-tokens.tsx index ad266eb8c..94116eb56 100644 --- a/frontend/src/components/profile-page/access-tokens/profile-access-tokens.tsx +++ b/frontend/src/components/profile-page/access-tokens/profile-access-tokens.tsx @@ -1,11 +1,10 @@ /* - * SPDX-FileCopyrightText: 2022 The HedgeDoc developers (see AUTHORS file) + * SPDX-FileCopyrightText: 2023 The HedgeDoc developers (see AUTHORS file) * * SPDX-License-Identifier: AGPL-3.0-only */ import { getAccessTokenList } from '../../../api/tokens' import type { AccessToken } from '../../../api/tokens/types' -import { ShowIf } from '../../common/show-if/show-if' import { useUiNotifications } from '../../notifications/ui-notification-boundary' import { AccessTokenCreationForm } from './access-token-creation-form/access-token-creation-form' import { AccessTokenListEntry } from './access-token-list-entry' @@ -58,14 +57,10 @@ export const ProfileAccessTokens: React.FC = () => { <Trans i18nKey='profile.accessTokens.infoDev' /> </p> <hr /> - <ShowIf condition={accessTokens.length === 0}> - <Trans i18nKey='profile.accessTokens.noTokens' /> - </ShowIf> + {accessTokens.length === 0 && <Trans i18nKey='profile.accessTokens.noTokens' />} <ListGroup>{tokensDom}</ListGroup> <hr /> - <ShowIf condition={accessTokens.length < 200}> - <AccessTokenCreationForm onUpdateList={refreshAccessTokens} /> - </ShowIf> + {accessTokens.length < 200 && <AccessTokenCreationForm onUpdateList={refreshAccessTokens} />} </Card.Body> </Card> ) diff --git a/frontend/src/components/register-page/register-infos.tsx b/frontend/src/components/register-page/register-infos.tsx index 290e62058..a6f73fcec 100644 --- a/frontend/src/components/register-page/register-infos.tsx +++ b/frontend/src/components/register-page/register-infos.tsx @@ -5,7 +5,6 @@ */ import { useFrontendConfig } from '../common/frontend-config-context/use-frontend-config' import { TranslatedExternalLink } from '../common/links/translated-external-link' -import { ShowIf } from '../common/show-if/show-if' import React from 'react' import { Trans, useTranslation } from 'react-i18next' @@ -16,21 +15,25 @@ export const RegisterInfos: React.FC = () => { useTranslation() const specialUrls = useFrontendConfig().specialUrls + if (specialUrls.termsOfUse === undefined && specialUrls.privacy === undefined) { + return null + } + return ( - <ShowIf condition={!!specialUrls.termsOfUse || !!specialUrls.privacy}> + <> <Trans i18nKey='login.register.infoTermsPrivacy' /> <ul> - <ShowIf condition={!!specialUrls.termsOfUse}> + {specialUrls.termsOfUse !== undefined && ( <li> <TranslatedExternalLink i18nKey='appbar.help.legal.termsOfUse' href={specialUrls.termsOfUse ?? ''} /> </li> - </ShowIf> - <ShowIf condition={!!specialUrls.privacy}> + )} + {specialUrls.privacy !== undefined && ( <li> <TranslatedExternalLink i18nKey='appbar.help.legal.privacy' href={specialUrls.privacy ?? ''} /> </li> - </ShowIf> + )} </ul> - </ShowIf> + </> ) } diff --git a/frontend/src/components/render-page/renderers/document/document-toc-sidebar.tsx b/frontend/src/components/render-page/renderers/document/document-toc-sidebar.tsx index 8907947dd..17c091742 100644 --- a/frontend/src/components/render-page/renderers/document/document-toc-sidebar.tsx +++ b/frontend/src/components/render-page/renderers/document/document-toc-sidebar.tsx @@ -1,10 +1,9 @@ /* - * SPDX-FileCopyrightText: 2022 The HedgeDoc developers (see AUTHORS file) + * SPDX-FileCopyrightText: 2023 The HedgeDoc developers (see AUTHORS file) * * SPDX-License-Identifier: AGPL-3.0-only */ import { TableOfContentsMarkdownExtension } from '../../../../extensions/essential-app-extensions/table-of-contents/table-of-contents-markdown-extension' -import { ShowIf } from '../../../common/show-if/show-if' import { useExtensionEventEmitterHandler } from '../../../markdown-renderer/hooks/use-extension-event-emitter' import styles from './markdown-document.module.scss' import { WidthBasedTableOfContents } from './width-based-table-of-contents' @@ -22,9 +21,7 @@ export const DocumentTocSidebar: React.FC<DocumentTocSidebarProps> = ({ width, b return ( <div className={styles.side}> - <ShowIf condition={!!tocAst}> - <WidthBasedTableOfContents tocAst={tocAst as TocAst} baseUrl={baseUrl} width={width} /> - </ShowIf> + {tocAst !== undefined && <WidthBasedTableOfContents tocAst={tocAst} baseUrl={baseUrl} width={width} />} </div> ) } diff --git a/frontend/src/extensions/external-lib-app-extensions/abcjs/abc-frame.tsx b/frontend/src/extensions/external-lib-app-extensions/abcjs/abc-frame.tsx index 89cc0a8ad..f8f50ba5f 100644 --- a/frontend/src/extensions/external-lib-app-extensions/abcjs/abc-frame.tsx +++ b/frontend/src/extensions/external-lib-app-extensions/abcjs/abc-frame.tsx @@ -1,10 +1,9 @@ /* - * SPDX-FileCopyrightText: 2022 The HedgeDoc developers (see AUTHORS file) + * SPDX-FileCopyrightText: 2023 The HedgeDoc developers (see AUTHORS file) * * SPDX-License-Identifier: AGPL-3.0-only */ import { AsyncLoadingBoundary } from '../../../components/common/async-loading-boundary/async-loading-boundary' -import { ShowIf } from '../../../components/common/show-if/show-if' import { WaitSpinner } from '../../../components/common/wait-spinner/wait-spinner' import type { CodeProps } from '../../../components/markdown-renderer/replace-components/code-block-component-replacer' import { useEffectWithCatch } from '../../../hooks/common/use-effect-with-catch' @@ -49,9 +48,9 @@ export const AbcFrame: React.FC<CodeProps> = ({ code }) => { return ( <AsyncLoadingBoundary loading={loading || !abcLib} error={!!loadingError} componentName={'abc.js'}> - <ShowIf condition={!!renderError}> + {renderError !== undefined && ( <TranslatedApplicationErrorAlert errorI18nKey={'editor.embeddings.abcJs.errorWhileRendering'} /> - </ShowIf> + )} <div ref={container} className={`${styles['abcjs-score']} bg-white text-black svg-container`} diff --git a/frontend/src/extensions/external-lib-app-extensions/flowchart/flowchart.tsx b/frontend/src/extensions/external-lib-app-extensions/flowchart/flowchart.tsx index a08b7c085..90a802bc4 100644 --- a/frontend/src/extensions/external-lib-app-extensions/flowchart/flowchart.tsx +++ b/frontend/src/extensions/external-lib-app-extensions/flowchart/flowchart.tsx @@ -1,11 +1,10 @@ /* - * SPDX-FileCopyrightText: 2022 The HedgeDoc developers (see AUTHORS file) + * SPDX-FileCopyrightText: 2023 The HedgeDoc developers (see AUTHORS file) * * SPDX-License-Identifier: AGPL-3.0-only */ import fontStyles from '../../../../global-styles/variables.module.scss' import { AsyncLoadingBoundary } from '../../../components/common/async-loading-boundary/async-loading-boundary' -import { ShowIf } from '../../../components/common/show-if/show-if' import type { CodeProps } from '../../../components/markdown-renderer/replace-components/code-block-component-replacer' import { useDarkModeState } from '../../../hooks/dark-mode/use-dark-mode-state' import { Logger } from '../../../utils/logger' @@ -71,9 +70,7 @@ export const FlowChart: React.FC<CodeProps> = ({ code }) => { return ( <AsyncLoadingBoundary loading={loading || !flowchartLib} componentName={'flowchart.js'} error={!!libLoadingError}> - <ShowIf condition={syntaxError}> - <TranslatedApplicationErrorAlert errorI18nKey={'renderer.flowchart.invalidSyntax'} /> - </ShowIf> + {syntaxError && <TranslatedApplicationErrorAlert errorI18nKey={'renderer.flowchart.invalidSyntax'} />} <div ref={diagramRef} {...testId('flowchart')} className={'text-center'} /> </AsyncLoadingBoundary> ) diff --git a/frontend/src/extensions/external-lib-app-extensions/graphviz/graphviz-frame.tsx b/frontend/src/extensions/external-lib-app-extensions/graphviz/graphviz-frame.tsx index 9544da45f..fba9b3bfe 100644 --- a/frontend/src/extensions/external-lib-app-extensions/graphviz/graphviz-frame.tsx +++ b/frontend/src/extensions/external-lib-app-extensions/graphviz/graphviz-frame.tsx @@ -1,10 +1,9 @@ /* - * SPDX-FileCopyrightText: 2022 The HedgeDoc developers (see AUTHORS file) + * SPDX-FileCopyrightText: 2023 The HedgeDoc developers (see AUTHORS file) * * SPDX-License-Identifier: AGPL-3.0-only */ import { AsyncLoadingBoundary } from '../../../components/common/async-loading-boundary/async-loading-boundary' -import { ShowIf } from '../../../components/common/show-if/show-if' import type { CodeProps } from '../../../components/markdown-renderer/replace-components/code-block-component-replacer' import { cypressId } from '../../../utils/cypress-attribute' import { Logger } from '../../../utils/logger' @@ -59,9 +58,7 @@ export const GraphvizFrame: React.FC<CodeProps> = ({ code }) => { return ( <AsyncLoadingBoundary loading={isLibLoading || !graphvizImport} componentName={'graphviz'} error={libLoadingError}> - <ShowIf condition={!!error}> - <ApplicationErrorAlert className={'text-wrap'}>{error}</ApplicationErrorAlert> - </ShowIf> + {error !== undefined && <ApplicationErrorAlert className={'text-wrap'}>{error}</ApplicationErrorAlert>} <div className={'svg-container'} {...cypressId('graphviz')} ref={container} /> </AsyncLoadingBoundary> ) diff --git a/frontend/src/extensions/external-lib-app-extensions/mermaid/mermaid-chart.tsx b/frontend/src/extensions/external-lib-app-extensions/mermaid/mermaid-chart.tsx index df229050d..36a899c4e 100644 --- a/frontend/src/extensions/external-lib-app-extensions/mermaid/mermaid-chart.tsx +++ b/frontend/src/extensions/external-lib-app-extensions/mermaid/mermaid-chart.tsx @@ -1,9 +1,8 @@ /* - * SPDX-FileCopyrightText: 2022 The HedgeDoc developers (see AUTHORS file) + * SPDX-FileCopyrightText: 2023 The HedgeDoc developers (see AUTHORS file) * * SPDX-License-Identifier: AGPL-3.0-only */ -import { ShowIf } from '../../../components/common/show-if/show-if' import type { CodeProps } from '../../../components/markdown-renderer/replace-components/code-block-component-replacer' import { cypressId } from '../../../utils/cypress-attribute' import { Logger } from '../../../utils/logger' @@ -65,9 +64,7 @@ export const MermaidChart: React.FC<CodeProps> = ({ code }) => { return ( <Fragment> - <ShowIf condition={!!error}> - <ApplicationErrorAlert className={'text-wrap'}>{error?.message}</ApplicationErrorAlert> - </ShowIf> + {error !== undefined && <ApplicationErrorAlert className={'text-wrap'}>{error?.message}</ApplicationErrorAlert>} <div {...cypressId('mermaid-frame')} className={`text-center ${styles['mermaid']} bg-dark text-black`} diff --git a/frontend/src/extensions/external-lib-app-extensions/vega-lite/vega-lite-chart.tsx b/frontend/src/extensions/external-lib-app-extensions/vega-lite/vega-lite-chart.tsx index 0bce2588e..1bca388a9 100644 --- a/frontend/src/extensions/external-lib-app-extensions/vega-lite/vega-lite-chart.tsx +++ b/frontend/src/extensions/external-lib-app-extensions/vega-lite/vega-lite-chart.tsx @@ -1,10 +1,9 @@ /* - * SPDX-FileCopyrightText: 2022 The HedgeDoc developers (see AUTHORS file) + * SPDX-FileCopyrightText: 2023 The HedgeDoc developers (see AUTHORS file) * * SPDX-License-Identifier: AGPL-3.0-only */ import { AsyncLoadingBoundary } from '../../../components/common/async-loading-boundary/async-loading-boundary' -import { ShowIf } from '../../../components/common/show-if/show-if' import type { CodeProps } from '../../../components/markdown-renderer/replace-components/code-block-component-replacer' import { Logger } from '../../../utils/logger' import React, { useEffect, useRef } from 'react' @@ -59,9 +58,9 @@ export const VegaLiteChart: React.FC<CodeProps> = ({ code }) => { return ( <AsyncLoadingBoundary loading={libLoading || !vegaEmbed} error={libLoadingError} componentName={'Vega Lite'}> - <ShowIf condition={!!renderingError}> + {renderingError !== undefined && ( <TranslatedApplicationErrorAlert errorI18nKey={'renderer.vega-lite.errorJson'} /> - </ShowIf> + )} <div className={'text-center'}> <div ref={diagramContainer} /> </div>