From 3e5349d5d17eeade4d685817efd0289d2801250b Mon Sep 17 00:00:00 2001 From: Konstantin Schaper Date: Wed, 23 Sep 2020 14:34:21 +0200 Subject: [PATCH 01/40] refactor modal and confirm alert --- .../src/modals/ConfirmAlert.stories.tsx | 18 ++++- .../ui-components/src/modals/ConfirmAlert.tsx | 81 +++++++++++-------- scm-ui/ui-components/src/modals/Modal.tsx | 61 +++++++------- 3 files changed, 93 insertions(+), 67 deletions(-) diff --git a/scm-ui/ui-components/src/modals/ConfirmAlert.stories.tsx b/scm-ui/ui-components/src/modals/ConfirmAlert.stories.tsx index b450153c3b..6be1ce43ee 100644 --- a/scm-ui/ui-components/src/modals/ConfirmAlert.stories.tsx +++ b/scm-ui/ui-components/src/modals/ConfirmAlert.stories.tsx @@ -25,7 +25,7 @@ import { storiesOf } from "@storybook/react"; import { MemoryRouter } from "react-router-dom"; import * as React from "react"; -import ConfirmAlert from "./ConfirmAlert"; +import ConfirmAlert, { confirmAlert } from "./ConfirmAlert"; const body = "Mind-paralyzing change needed improbability vortex machine sorts sought same theory upending job just allows\n " + @@ -40,11 +40,21 @@ const buttons = [ onClick: () => null }, { - label: "Submit", - onClick: () => {} + label: "Submit" } ]; storiesOf("Modal|ConfirmAlert", module) .addDecorator(story => {story()}) - .add("Default", () => ); + .add("Default", () => ) + .add("WithButton", () => { + const buttonClick = () => { + confirmAlert({ message: body, title: "Are you sure about that?", buttons }); + }; + return ( + <> + +
+ + ); + }); diff --git a/scm-ui/ui-components/src/modals/ConfirmAlert.tsx b/scm-ui/ui-components/src/modals/ConfirmAlert.tsx index e8671a77cb..ee0265d89d 100644 --- a/scm-ui/ui-components/src/modals/ConfirmAlert.tsx +++ b/scm-ui/ui-components/src/modals/ConfirmAlert.tsx @@ -22,6 +22,7 @@ * SOFTWARE. */ import * as React from "react"; +import { FC, useState } from "react"; import ReactDOM from "react-dom"; import Modal from "./Modal"; import classNames from "classnames"; @@ -29,59 +30,71 @@ import classNames from "classnames"; type Button = { className?: string; label: string; - onClick: () => void | null; + onClick?: () => void | null; }; type Props = { title: string; message: string; buttons: Button[]; + close?: () => void; }; -class ConfirmAlert extends React.Component { - handleClickButton = (button: Button) => { +export const ConfirmAlert: FC = ({ title, message, buttons, close }) => { + const [showModal, setShowModal] = useState(true); + + const onClose = () => { + if (typeof close === "function") { + close(); + } else { + setShowModal(false); + } + }; + + const handleClickButton = (button: Button) => { if (button.onClick) { button.onClick(); } - this.close(); + onClose(); }; - close = () => { - const container = document.getElementById("modalRoot"); - if (container) { - ReactDOM.unmountComponentAtNode(container); - } - }; + const body = <>{message}; - render() { - const { title, message, buttons } = this.props; + const footer = ( +
+ {buttons.map((button, i) => ( +

+ handleClickButton(button)} + > + {button.label} + +

+ ))} +
+ ); - const body = <>{message}; - - const footer = ( -
- {buttons.map((button, i) => ( -

- this.handleClickButton(button)} - > - {button.label} - -

- ))} -
- ); - - return this.close()} body={body} active={true} footer={footer} />; - } -} + return ( + (showModal && ) || null + ); +}; +/** + * @deprecated Use the {@link ConfirmAlert} component directly instead. + */ export function confirmAlert(properties: Props) { const root = document.getElementById("modalRoot"); if (root) { - ReactDOM.render(, root); + const close = () => { + const container = document.getElementById("modalRoot"); + if (container) { + ReactDOM.unmountComponentAtNode(container); + } + }; + const props = { ...properties, close }; + ReactDOM.render(, root); } } diff --git a/scm-ui/ui-components/src/modals/Modal.tsx b/scm-ui/ui-components/src/modals/Modal.tsx index 19ce82dea0..87badb5d4b 100644 --- a/scm-ui/ui-components/src/modals/Modal.tsx +++ b/scm-ui/ui-components/src/modals/Modal.tsx @@ -22,7 +22,10 @@ * SOFTWARE. */ import * as React from "react"; +import {FC} from "react"; import classNames from "classnames"; +import usePortalRootElement from "../usePortalRootElement"; +import ReactDOM from "react-dom"; type Props = { title: string; @@ -31,38 +34,38 @@ type Props = { footer?: any; active: boolean; className?: string; - headColor: string; + headColor?: string; }; -class Modal extends React.Component { - static defaultProps = { - headColor: "light" - }; +export const Modal: FC = ({ title, closeFunction, body, footer, active, className, headColor = "light" }) => { + const portalRootElement = usePortalRootElement("modalsRoot"); - render() { - const { title, closeFunction, body, footer, active, className, headColor } = this.props; - - const isActive = active ? "is-active" : null; - - let showFooter = null; - if (footer) { - showFooter =
{footer}
; - } - - return ( -
-
-
-
-

{title}

-
-
{body}
- {showFooter} -
-
- ); + if (!portalRootElement) { + return null; } -} + + const isActive = active ? "is-active" : null; + + let showFooter = null; + if (footer) { + showFooter =
{footer}
; + } + + const modalElement = ( +
+
+
+
+

{title}

+
+
{body}
+ {showFooter} +
+
+ ); + + return ReactDOM.createPortal(modalElement, portalRootElement); +}; export default Modal; From a169e64e0911f2b82c6aa92ba4c566630b479a2c Mon Sep 17 00:00:00 2001 From: Konstantin Schaper Date: Thu, 24 Sep 2020 09:12:37 +0200 Subject: [PATCH 02/40] revert deprecation for later redeclaration --- scm-ui/ui-components/src/modals/ConfirmAlert.tsx | 3 --- 1 file changed, 3 deletions(-) diff --git a/scm-ui/ui-components/src/modals/ConfirmAlert.tsx b/scm-ui/ui-components/src/modals/ConfirmAlert.tsx index ee0265d89d..45726d314b 100644 --- a/scm-ui/ui-components/src/modals/ConfirmAlert.tsx +++ b/scm-ui/ui-components/src/modals/ConfirmAlert.tsx @@ -81,9 +81,6 @@ export const ConfirmAlert: FC = ({ title, message, buttons, close }) => { ); }; -/** - * @deprecated Use the {@link ConfirmAlert} component directly instead. - */ export function confirmAlert(properties: Props) { const root = document.getElementById("modalRoot"); if (root) { From fec498751cc55f916946623f12b6dc55e0101f7b Mon Sep 17 00:00:00 2001 From: Konstantin Schaper Date: Thu, 24 Sep 2020 09:16:51 +0200 Subject: [PATCH 03/40] update changelog --- CHANGELOG.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index ed03e68e98..a9b708447c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Tags overview for repository [#1331](https://github.com/scm-manager/scm-manager/pull/1331) - Permissions can be specified for namespaces ([#1335](https://github.com/scm-manager/scm-manager/pull/1335)) +### Changed +- Rework modal to use react portal ([#1349](https://github.com/scm-manager/scm-manager/pull/1349)) + ### Fixed - Missing synchronization during repository creation ([#1328](https://github.com/scm-manager/scm-manager/pull/1328)) - Missing BranchCreatedEvent for mercurial ([#1334](https://github.com/scm-manager/scm-manager/pull/1334)) From e69e918d55bb09875410220189fdea57a44a599b Mon Sep 17 00:00:00 2001 From: Konstantin Schaper Date: Thu, 24 Sep 2020 10:18:43 +0200 Subject: [PATCH 04/40] update storyshots --- .../src/__snapshots__/storyshots.test.ts.snap | 579 +----------------- 1 file changed, 17 insertions(+), 562 deletions(-) diff --git a/scm-ui/ui-components/src/__snapshots__/storyshots.test.ts.snap b/scm-ui/ui-components/src/__snapshots__/storyshots.test.ts.snap index 88861f1fd9..e5ed258452 100644 --- a/scm-ui/ui-components/src/__snapshots__/storyshots.test.ts.snap +++ b/scm-ui/ui-components/src/__snapshots__/storyshots.test.ts.snap @@ -47242,575 +47242,30 @@ exports[`Storyshots MarkdownView Xml Code Block 1`] = `
`; -exports[`Storyshots Modal|ConfirmAlert Default 1`] = ` -
-
-
-
-

- Are you sure about that? -

-
-
- Mind-paralyzing change needed improbability vortex machine sorts sought same theory upending job just allows - hostess’s really oblong Infinite Improbability thing into the starship against which behavior accordance with - Kakrafoon humanoid undergarment ship powered by GPP-guided bowl of petunias nothing was frequently away incredibly - ordinary mob. -
- -
-
+ Open ConfirmAlert + , +
, +] `; -exports[`Storyshots Modal|Modal Closeable 1`] = ` -
-
-
-
-

- Hitchhiker Modal -

-
-
-

- Mind-paralyzing change needed improbability vortex machine sorts sought same theory upending job just allows - hostess’s really oblong Infinite Improbability thing into the starship against which behavior accordance.with - Kakrafoon humanoid undergarment ship powered by GPP-guided bowl of petunias nothing was frequently away incredibly - ordinary mob. -

-
-
-
-`; +exports[`Storyshots Modal|Modal Closeable 1`] = `null`; -exports[`Storyshots Modal|Modal Default 1`] = ` -
-
-
-
-

- Hitchhiker Modal -

-
-
-

- Mind-paralyzing change needed improbability vortex machine sorts sought same theory upending job just allows - hostess’s really oblong Infinite Improbability thing into the starship against which behavior accordance.with - Kakrafoon humanoid undergarment ship powered by GPP-guided bowl of petunias nothing was frequently away incredibly - ordinary mob. -

-
-
-
-`; +exports[`Storyshots Modal|Modal Default 1`] = `null`; -exports[`Storyshots Modal|Modal Long content 1`] = ` -
-
-
-
-

- Hitchhiker Modal -

-
-
-

- Marvin -

-

- The Paranoid Android -

-
-
- - The following content comes from the awesome - - - Hitchhikers Wiki - -
-
-
- Marvin -
-
-

- Marvin, more fully known as Marvin the Paranoid Android, is an incredibly brilliant but overwhelmingly depressed robot manufactured by the Sirius Cybernetics Corporation and unwilling servant to the crew of the Heart of Gold. -

-
-
-

- Physical Appearance -

-

- In the novels, Marvin is described thusly: "...though it was beautifully constructed and polished it looked somehow as if the various parts of its more or less humanoid body didn't quite fit properly. In fact, they fit perfectly well, but something in its bearing suggested that they might have fitted better." -

-

- On the radio show, there's no physical description of Marvin, though his voice is digitally altered to sound more robotic, and any scene that focuses on him is accompanied by sounds of mechanical clanking and hissing. -

-

- In the TV series, Marvin is built in the style of a 1950's robot similar to Robbie the Robot from Forbidden Planet or Twiki from Buck Rogers. His body is blocky and angular, with a pair of clamp-claw hands, shuffling feet and a squarish head with a dour face. -

-

- In the movie, Marvin is a short, stout robot built of smooth, white plastic. His arms are much longer than his legs, and his head is a massive sphere with only a pair of triangle eyes for a face. His large head and simian-like proportions give Marvin a perpetual slouch, adding to his melancholy personality. At the start of the film his eyes glow, but at the end he is shot but unharmed, leaving a hole in his head and dimming his eyes. This is probably the most depressing and unacceptable manifestation of Marvin ever conceived, and thus paradoxically the most accurate. -

-
-
-
-

- Personality -

-

- Marvin the robot has a prototype version of the Genuine People Personality (GPP) software from SCC, allowing him sentience and the ability to feel emotions and develop a personality. He's also incredibly smart, having a "brain the size of a planet" capable of computing extremely complex mathematics, as well as solving difficult problems and operating high-tech devices. -

-

- However, despite being so smart, Marvin is typically made to perform menial tasks and labour such as escorting people, opening doors, picking up pieces of paper, and other tasks well beneath his skills. Even extremely hard tasks, such as computing for the vast Krikkit robot army, are trivial for Marvin. All this leaves him extremely bored, frustrated, and overwhelmingly depressed. Because of this, all modern GPP-capable machines, such as Eddie the computer and the Heart of Gold's automatic doors, are programmed to be extremely cheerful and happy, much to Marvin's disgust. -

-

- Marvin hates everyone and everything he comes into contact with, having no respect for anybody and will criticise and insult others at any opportunity, or otherwise rant and complain for hours on end about his own problems, such as the terrible pain he suffers in all the diodes down his left side. His contempt for everyone is often justified, as almost every person he comes across, even those who consider him a friend, (such as Arthur and Trillian, who treat him more kindly than Ford and Zaphod) treat Marvin as an expendable servant, even sending him to his death more than once (such as when Zaphod ordered Marvin to fight the gigantic, heavy-duty Frogstar Scout Robot Class D so he could escape). Being a robot, he still does what he's told (he won't enjoy it, nor will he let you forget it, but he'll do it anyway), though he'd much rather sulk in a corner by himself. -

-

- Several times in the series Marvin ends up alone and isolated for extremely long periods of time, sometimes spanning millions of years, either by sheer bad luck (such as the explosion that propelled everyone but Marvin to Milliways in the far-off future) or because his unpleasantly depressing personality drives them away or, in more than one case, makes them commit suicide. In his spare time (which he has a lot of), Marvin will attempt to occupy himself by composing songs and writing poetry. Of course, none of them are particularly cheerful, or even that good. -

-
-
-
-
-`; +exports[`Storyshots Modal|Modal Long content 1`] = `null`; -exports[`Storyshots Modal|Modal With form elements 1`] = ` -
-
-
-
-

- Hitchhiker Modal -

-
-
-
- - -
-
-

- Mind-paralyzing change needed improbability vortex machine sorts sought same theory upending job just allows - hostess’s really oblong Infinite Improbability thing into the starship against which behavior accordance.with - Kakrafoon humanoid undergarment ship powered by GPP-guided bowl of petunias nothing was frequently away incredibly - ordinary mob. -

-
-
- -
-