aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorLibravatar muhamedsalih-tw <104364298+muhamedsalih-tw@users.noreply.github.com>2022-10-25 12:51:28 +0530
committerLibravatar GitHub <noreply@github.com>2022-10-25 07:21:28 +0000
commitf79727a8632490f11c1423773fdd6adfb6337a7b (patch)
treea80943f4e4e571359c8104341a3957f6e763dce4 /src
parentadd balajiv113 as a contributor for code (#701) [skip ci] (diff)
downloadferdium-app-f79727a8632490f11c1423773fdd6adfb6337a7b.tar.gz
ferdium-app-f79727a8632490f11c1423773fdd6adfb6337a7b.tar.zst
ferdium-app-f79727a8632490f11c1423773fdd6adfb6337a7b.zip
Transform 'AuthLayoutContainer' component hierarchy to tsx (#699)
Co-authored-by: Muhamed <> Co-authored-by: Vijay A <vraravam@users.noreply.github.com>
Diffstat (limited to 'src')
-rw-r--r--src/components/AppUpdateInfoBar.tsx14
-rw-r--r--src/components/auth/AuthLayout.tsx (renamed from src/components/auth/AuthLayout.jsx)61
-rw-r--r--src/components/ui/AppLoader/index.tsx68
-rw-r--r--src/components/ui/AppLoader/styles.ts9
-rw-r--r--src/components/ui/InfoBar.tsx (renamed from src/components/ui/InfoBar.js)70
-rw-r--r--src/components/ui/Modal/index.tsx36
-rw-r--r--src/components/ui/headline/index.tsx15
-rw-r--r--src/components/ui/icon/index.tsx10
-rw-r--r--src/components/ui/input/index.tsx59
-rw-r--r--src/containers/auth/AuthLayoutContainer.tsx10
-rw-r--r--src/features/publishDebugInfo/Component.tsx (renamed from src/features/publishDebugInfo/Component.js)95
-rw-r--r--src/features/publishDebugInfo/index.ts14
-rw-r--r--src/routes.tsx30
13 files changed, 218 insertions, 273 deletions
diff --git a/src/components/AppUpdateInfoBar.tsx b/src/components/AppUpdateInfoBar.tsx
index 3ff488b74..ff4a9b9ad 100644
--- a/src/components/AppUpdateInfoBar.tsx
+++ b/src/components/AppUpdateInfoBar.tsx
@@ -1,6 +1,7 @@
1import { defineMessages, useIntl } from 'react-intl'; 1import { defineMessages, useIntl } from 'react-intl';
2 2
3import { mdiInformation } from '@mdi/js'; 3import { mdiInformation } from '@mdi/js';
4import { MouseEventHandler } from 'react';
4import InfoBar from './ui/InfoBar'; 5import InfoBar from './ui/InfoBar';
5import Icon from './ui/icon'; 6import Icon from './ui/icon';
6 7
@@ -21,17 +22,14 @@ const messages = defineMessages({
21 }, 22 },
22}); 23});
23 24
24type Props = { 25export interface IProps {
25 onInstallUpdate: () => void; 26 onInstallUpdate: MouseEventHandler<HTMLButtonElement>;
26 onHide: () => void; 27 onHide: () => void;
27 updateVersionParsed: string; 28 updateVersionParsed: string;
28}; 29}
29 30
30const AppUpdateInfoBar = ({ 31const AppUpdateInfoBar = (props: IProps) => {
31 onInstallUpdate, 32 const { onInstallUpdate, updateVersionParsed, onHide } = props;
32 updateVersionParsed,
33 onHide,
34}: Props) => {
35 const intl = useIntl(); 33 const intl = useIntl();
36 34
37 return ( 35 return (
diff --git a/src/components/auth/AuthLayout.jsx b/src/components/auth/AuthLayout.tsx
index 5c87c3080..527c2bb74 100644
--- a/src/components/auth/AuthLayout.jsx
+++ b/src/components/auth/AuthLayout.tsx
@@ -1,52 +1,53 @@
1import { cloneElement, Component } from 'react'; 1import {
2import PropTypes from 'prop-types'; 2 cloneElement,
3 Component,
4 MouseEventHandler,
5 ReactElement,
6} from 'react';
3import { observer } from 'mobx-react'; 7import { observer } from 'mobx-react';
4import { TitleBar } from 'electron-react-titlebar/renderer'; 8import { TitleBar } from 'electron-react-titlebar/renderer';
5 9import { injectIntl, WrappedComponentProps } from 'react-intl';
6import { injectIntl } from 'react-intl';
7import { mdiFlash } from '@mdi/js'; 10import { mdiFlash } from '@mdi/js';
11import { GlobalError } from '../../@types/ferdium-components.types';
8import Link from '../ui/Link'; 12import Link from '../ui/Link';
9import InfoBar from '../ui/InfoBar'; 13import InfoBar from '../ui/InfoBar';
10
11import { Component as PublishDebugInfo } from '../../features/publishDebugInfo'; 14import { Component as PublishDebugInfo } from '../../features/publishDebugInfo';
12
13import {
14 oneOrManyChildElements,
15 globalError as globalErrorPropType,
16} from '../../prop-types';
17import { updateVersionParse } from '../../helpers/update-helpers'; 15import { updateVersionParse } from '../../helpers/update-helpers';
18import globalMessages from '../../i18n/globalMessages'; 16import globalMessages from '../../i18n/globalMessages';
19
20import { isWindows } from '../../environment'; 17import { isWindows } from '../../environment';
21import AppUpdateInfoBar from '../AppUpdateInfoBar'; 18import AppUpdateInfoBar from '../AppUpdateInfoBar';
22import { GITHUB_FERDIUM_URL } from '../../config'; 19import { GITHUB_FERDIUM_URL } from '../../config';
23import Icon from '../ui/icon'; 20import Icon from '../ui/icon';
24
25import { serverName } from '../../api/apiBase'; 21import { serverName } from '../../api/apiBase';
26 22
27class AuthLayout extends Component { 23export interface IProps extends WrappedComponentProps {
28 static propTypes = { 24 children: ReactElement;
29 children: oneOrManyChildElements.isRequired, 25 error: GlobalError;
30 error: globalErrorPropType.isRequired, 26 isOnline: boolean;
31 isOnline: PropTypes.bool.isRequired, 27 isAPIHealthy: boolean;
32 isAPIHealthy: PropTypes.bool.isRequired, 28 retryHealthCheck: MouseEventHandler<HTMLButtonElement>;
33 retryHealthCheck: PropTypes.func.isRequired, 29 isHealthCheckLoading: boolean;
34 isHealthCheckLoading: PropTypes.bool.isRequired, 30 isFullScreen: boolean;
35 isFullScreen: PropTypes.bool.isRequired, 31 installAppUpdate: MouseEventHandler<HTMLButtonElement>;
36 installAppUpdate: PropTypes.func.isRequired, 32 appUpdateIsDownloaded: boolean;
37 appUpdateIsDownloaded: PropTypes.bool.isRequired, 33 updateVersion: string;
38 updateVersion: PropTypes.string.isRequired, 34}
39 }; 35
36interface IState {
37 shouldShowAppUpdateInfoBar: boolean;
38}
40 39
41 constructor() { 40@observer
42 super(); 41class AuthLayout extends Component<IProps, IState> {
42 constructor(props: IProps) {
43 super(props);
43 44
44 this.state = { 45 this.state = {
45 shouldShowAppUpdateInfoBar: true, 46 shouldShowAppUpdateInfoBar: true,
46 }; 47 };
47 } 48 }
48 49
49 render() { 50 render(): ReactElement {
50 const { 51 const {
51 children, 52 children,
52 error, 53 error,
@@ -58,9 +59,9 @@ class AuthLayout extends Component {
58 installAppUpdate, 59 installAppUpdate,
59 appUpdateIsDownloaded, 60 appUpdateIsDownloaded,
60 updateVersion, 61 updateVersion,
62 intl,
61 } = this.props; 63 } = this.props;
62 64
63 const { intl } = this.props;
64 let serverNameParse = serverName(); 65 let serverNameParse = serverName();
65 serverNameParse = 66 serverNameParse =
66 serverNameParse === 'Custom' ? 'your Custom Server' : serverNameParse; 67 serverNameParse === 'Custom' ? 'your Custom Server' : serverNameParse;
@@ -124,4 +125,4 @@ class AuthLayout extends Component {
124 } 125 }
125} 126}
126 127
127export default injectIntl(observer(AuthLayout)); 128export default injectIntl(AuthLayout);
diff --git a/src/components/ui/AppLoader/index.tsx b/src/components/ui/AppLoader/index.tsx
index caa7e381d..f4d9b8e73 100644
--- a/src/components/ui/AppLoader/index.tsx
+++ b/src/components/ui/AppLoader/index.tsx
@@ -1,7 +1,7 @@
1import { Component } from 'react'; 1import { Component, ReactElement } from 'react';
2import classnames from 'classnames'; 2import classnames from 'classnames';
3 3import withStyles, { WithStylesProps } from 'react-jss';
4import injectStyle from 'react-jss'; 4import { Theme } from '../../../themes';
5import FullscreenLoader from '../FullscreenLoader'; 5import FullscreenLoader from '../FullscreenLoader';
6import shuffleArray from '../../../helpers/array-helpers'; 6import shuffleArray from '../../../helpers/array-helpers';
7 7
@@ -18,24 +18,27 @@ const textList = shuffleArray([
18 'Fixing bugs', 18 'Fixing bugs',
19]); 19]);
20 20
21type Props = { 21interface IProps extends WithStylesProps<typeof styles> {
22 classes: typeof styles; 22 theme: Theme;
23 theme: any; 23 texts?: string[];
24 texts: string[]; 24}
25};
26
27class AppLoader extends Component<Props> {
28 static defaultProps = {
29 texts: textList,
30 };
31 25
32 state = { 26interface IState {
33 step: 0, 27 step: number;
34 }; 28}
35 29
30class AppLoader extends Component<IProps, IState> {
36 interval: NodeJS.Timeout | null = null; 31 interval: NodeJS.Timeout | null = null;
37 32
38 componentDidMount() { 33 constructor(props: IProps) {
34 super(props);
35
36 this.state = {
37 step: 0,
38 };
39 }
40
41 componentDidMount(): void {
39 this.interval = setInterval(() => { 42 this.interval = setInterval(() => {
40 this.setState((prevState: { step: number }) => ({ 43 this.setState((prevState: { step: number }) => ({
41 step: prevState.step === textList.length - 1 ? 0 : prevState.step + 1, 44 step: prevState.step === textList.length - 1 ? 0 : prevState.step + 1,
@@ -43,14 +46,14 @@ class AppLoader extends Component<Props> {
43 }, 2500); 46 }, 2500);
44 } 47 }
45 48
46 componentWillUnmount() { 49 componentWillUnmount(): void {
47 if (this.interval) { 50 if (this.interval) {
48 clearInterval(this.interval); 51 clearInterval(this.interval);
49 } 52 }
50 } 53 }
51 54
52 render() { 55 render(): ReactElement {
53 const { classes, theme, texts } = this.props; 56 const { classes, theme, texts = textList } = this.props;
54 const { step } = this.state; 57 const { step } = this.state;
55 58
56 return ( 59 return (
@@ -58,20 +61,21 @@ class AppLoader extends Component<Props> {
58 className={classes.component} 61 className={classes.component}
59 spinnerColor={theme.colorAppLoaderSpinner} 62 spinnerColor={theme.colorAppLoaderSpinner}
60 > 63 >
61 {texts.map((text, i) => ( 64 {texts &&
62 <span 65 texts.map((text, i) => (
63 key={text} 66 <span
64 className={classnames({ 67 key={text}
65 [`${classes.slogan}`]: true, 68 className={classnames({
66 [`${classes.visible}`]: step === i, 69 [`${classes.slogan}`]: true,
67 })} 70 [`${classes.visible}`]: step === i,
68 > 71 })}
69 {text} 72 >
70 </span> 73 {text}
71 ))} 74 </span>
75 ))}
72 </FullscreenLoader> 76 </FullscreenLoader>
73 ); 77 );
74 } 78 }
75} 79}
76 80
77export default injectStyle(styles, { injectTheme: true })(AppLoader); 81export default withStyles(styles, { injectTheme: true })(AppLoader);
diff --git a/src/components/ui/AppLoader/styles.ts b/src/components/ui/AppLoader/styles.ts
index 9891e0387..6bf3b4f3c 100644
--- a/src/components/ui/AppLoader/styles.ts
+++ b/src/components/ui/AppLoader/styles.ts
@@ -1,8 +1,7 @@
1let sloganTransition = 'none'; 1const sloganTransition =
2 2 window && window.matchMedia('(prefers-reduced-motion: no-preference)')
3if (window && window.matchMedia('(prefers-reduced-motion: no-preference)')) { 3 ? 'opacity 1s ease'
4 sloganTransition = 'opacity 1s ease'; 4 : 'none';
5}
6 5
7export default { 6export default {
8 component: { 7 component: {
diff --git a/src/components/ui/InfoBar.js b/src/components/ui/InfoBar.tsx
index d73491da0..ef8f6ad6f 100644
--- a/src/components/ui/InfoBar.js
+++ b/src/components/ui/InfoBar.tsx
@@ -1,11 +1,11 @@
1import { Component } from 'react'; 1import { Component, MouseEventHandler, ReactNode } from 'react';
2import PropTypes from 'prop-types';
3import { observer } from 'mobx-react'; 2import { observer } from 'mobx-react';
4import classnames from 'classnames'; 3import classnames from 'classnames';
5import Loader from 'react-loader'; 4import Loader from 'react-loader';
6import { defineMessages, injectIntl } from 'react-intl'; 5import { defineMessages, injectIntl, WrappedComponentProps } from 'react-intl';
7 6
8import { mdiClose } from '@mdi/js'; 7import { mdiClose } from '@mdi/js';
8import { noop } from 'lodash';
9import Appear from './effects/Appear'; 9import Appear from './effects/Appear';
10import Icon from './icon'; 10import Icon from './icon';
11 11
@@ -16,51 +16,35 @@ const messages = defineMessages({
16 }, 16 },
17}); 17});
18 18
19// Should this file be converted into the coding style similar to './toggle/index.tsx'? 19interface IProps extends WrappedComponentProps {
20class InfoBar extends Component { 20 children: ReactNode;
21 static propTypes = { 21 onClick?: MouseEventHandler<HTMLButtonElement>;
22 // eslint-disable-next-line react/forbid-prop-types 22 type?: string;
23 children: PropTypes.any.isRequired, 23 className?: string;
24 onClick: PropTypes.func, 24 ctaLabel?: string;
25 type: PropTypes.string, 25 ctaLoading?: boolean;
26 className: PropTypes.string, 26 position?: string;
27 ctaLabel: PropTypes.string, 27 sticky?: boolean;
28 ctaLoading: PropTypes.bool, 28 onHide?: () => void;
29 position: PropTypes.string, 29}
30 sticky: PropTypes.bool,
31 onHide: PropTypes.func,
32 };
33
34 static defaultProps = {
35 onClick: () => null,
36 type: 'primary',
37 className: '',
38 ctaLabel: '',
39 ctaLoading: false,
40 position: 'bottom',
41 sticky: false,
42 onHide: () => null,
43 };
44 30
31@observer
32class InfoBar extends Component<IProps> {
45 render() { 33 render() {
46 const { 34 const {
47 children, 35 children,
48 type, 36 type = 'primary',
49 className, 37 onClick = noop,
50 ctaLabel, 38 className = '',
51 ctaLoading, 39 ctaLabel = '',
52 onClick, 40 ctaLoading = false,
53 position, 41 position = 'bottom',
54 sticky, 42 sticky = false,
55 onHide, 43 onHide = noop,
44 intl,
56 } = this.props; 45 } = this.props;
57 46
58 const { intl } = this.props; 47 const transitionName = position === 'top' ? 'slideDown' : 'slideUp';
59
60 let transitionName = 'slideUp';
61 if (position === 'top') {
62 transitionName = 'slideDown';
63 }
64 48
65 return ( 49 return (
66 <Appear 50 <Appear
@@ -102,4 +86,4 @@ class InfoBar extends Component {
102 } 86 }
103} 87}
104 88
105export default injectIntl(observer(InfoBar)); 89export default injectIntl(InfoBar);
diff --git a/src/components/ui/Modal/index.tsx b/src/components/ui/Modal/index.tsx
index 7407a686d..154beef0c 100644
--- a/src/components/ui/Modal/index.tsx
+++ b/src/components/ui/Modal/index.tsx
@@ -1,41 +1,33 @@
1import { Component, ReactChildren } from 'react'; 1import { Component, ReactNode } from 'react';
2import ReactModal from 'react-modal'; 2import ReactModal from 'react-modal';
3import classnames from 'classnames'; 3import classnames from 'classnames';
4import injectCSS from 'react-jss'; 4import injectCSS, { WithStylesProps } from 'react-jss';
5import { mdiClose } from '@mdi/js'; 5import { mdiClose } from '@mdi/js';
6 6
7import Icon from '../icon'; 7import Icon from '../icon';
8import styles from './styles'; 8import styles from './styles';
9 9
10type Props = { 10interface IProps extends WithStylesProps<typeof styles> {
11 children: ReactChildren; 11 children: ReactNode;
12 className: string;
13 classes: any;
14 isOpen: boolean; 12 isOpen: boolean;
15 portal: string;
16 close: () => void; 13 close: () => void;
17 shouldCloseOnOverlayClick: boolean; 14 className?: string | null;
18 showClose: boolean; 15 portal?: string;
19}; 16 shouldCloseOnOverlayClick?: boolean;
20 17 showClose?: boolean;
21class Modal extends Component<Props> { 18}
22 static defaultProps = {
23 className: null,
24 portal: 'modal-portal',
25 shouldCloseOnOverlayClick: false,
26 showClose: true,
27 };
28 19
20class Modal extends Component<IProps> {
29 render() { 21 render() {
30 const { 22 const {
31 children, 23 children,
32 className,
33 classes, 24 classes,
34 isOpen, 25 isOpen,
35 portal,
36 close, 26 close,
37 shouldCloseOnOverlayClick, 27 className = null,
38 showClose, 28 portal = 'modal-portal',
29 shouldCloseOnOverlayClick = false,
30 showClose = true,
39 } = this.props; 31 } = this.props;
40 32
41 return ( 33 return (
diff --git a/src/components/ui/headline/index.tsx b/src/components/ui/headline/index.tsx
index b5a5f695f..bebd8adcf 100644
--- a/src/components/ui/headline/index.tsx
+++ b/src/components/ui/headline/index.tsx
@@ -1,16 +1,22 @@
1import classnames from 'classnames'; 1import classnames from 'classnames';
2import { Component, createElement, ReactNode } from 'react'; 2import {
3 Component,
4 createElement,
5 MouseEventHandler,
6 ReactElement,
7 ReactNode,
8} from 'react';
3import injectStyle, { WithStylesProps } from 'react-jss'; 9import injectStyle, { WithStylesProps } from 'react-jss';
4 10
5import { Theme } from '../../../themes'; 11import { Theme } from '../../../themes';
6import { Omit } from '../typings/generic'; 12import { Omit } from '../typings/generic';
7 13
8interface IProps extends WithStylesProps<typeof styles> { 14interface IProps extends WithStylesProps<typeof styles> {
15 children: ReactNode;
9 level?: number; 16 level?: number;
10 className?: string; 17 className?: string;
11 children: string | ReactNode;
12 id?: string; 18 id?: string;
13 onClick?: () => void; 19 onClick?: MouseEventHandler<HTMLButtonElement>;
14} 20}
15 21
16const styles = (theme: Theme) => ({ 22const styles = (theme: Theme) => ({
@@ -40,7 +46,7 @@ const styles = (theme: Theme) => ({
40}); 46});
41 47
42class HeadlineComponent extends Component<IProps> { 48class HeadlineComponent extends Component<IProps> {
43 render() { 49 render(): ReactElement {
44 const { classes, level, className, children, id, onClick } = this.props; 50 const { classes, level, className, children, id, onClick } = this.props;
45 51
46 return createElement( 52 return createElement(
@@ -61,7 +67,6 @@ class HeadlineComponent extends Component<IProps> {
61} 67}
62 68
63const Headline = injectStyle(styles, { injectTheme: true })(HeadlineComponent); 69const Headline = injectStyle(styles, { injectTheme: true })(HeadlineComponent);
64
65const createH = (level: number) => (props: Omit<IProps, 'classes'>) => 70const createH = (level: number) => (props: Omit<IProps, 'classes'>) =>
66 ( 71 (
67 <Headline level={level} {...props}> 72 <Headline level={level} {...props}>
diff --git a/src/components/ui/icon/index.tsx b/src/components/ui/icon/index.tsx
index 7e13b98c7..5b432a194 100644
--- a/src/components/ui/icon/index.tsx
+++ b/src/components/ui/icon/index.tsx
@@ -1,6 +1,6 @@
1import MdiIcon from '@mdi/react'; 1import MdiIcon from '@mdi/react';
2import classnames from 'classnames'; 2import classnames from 'classnames';
3import { Component } from 'react'; 3import { Component, ReactElement } from 'react';
4import injectStyle, { WithStylesProps } from 'react-jss'; 4import injectStyle, { WithStylesProps } from 'react-jss';
5 5
6import { Theme } from '../../../themes'; 6import { Theme } from '../../../themes';
@@ -18,12 +18,8 @@ const styles = (theme: Theme) => ({
18}); 18});
19 19
20class IconComponent extends Component<IProps> { 20class IconComponent extends Component<IProps> {
21 public static defaultProps = { 21 render(): ReactElement {
22 size: 1, 22 const { classes, icon, size = 1, className } = this.props;
23 };
24
25 render() {
26 const { classes, icon, size, className } = this.props;
27 23
28 if (!icon) { 24 if (!icon) {
29 console.warn('No Icon specified'); 25 console.warn('No Icon specified');
diff --git a/src/components/ui/input/index.tsx b/src/components/ui/input/index.tsx
index aa282cce0..b19bb4bc9 100644
--- a/src/components/ui/input/index.tsx
+++ b/src/components/ui/input/index.tsx
@@ -3,14 +3,12 @@ import Icon from '@mdi/react';
3import classnames from 'classnames'; 3import classnames from 'classnames';
4import { Component, createRef, InputHTMLAttributes } from 'react'; 4import { Component, createRef, InputHTMLAttributes } from 'react';
5import injectSheet, { WithStylesProps } from 'react-jss'; 5import injectSheet, { WithStylesProps } from 'react-jss';
6 6import { noop } from 'lodash';
7import { IFormField } from '../typings/generic'; 7import { IFormField } from '../typings/generic';
8
9import Error from '../error'; 8import Error from '../error';
10import Label from '../label'; 9import Label from '../label';
11import Wrapper from '../wrapper'; 10import Wrapper from '../wrapper';
12import { scorePasswordFunc } from './scorePassword'; 11import { scorePasswordFunc } from './scorePassword';
13
14import styles from './styles'; 12import styles from './styles';
15 13
16interface IData { 14interface IData {
@@ -26,7 +24,7 @@ interface IProps
26 suffix?: string; 24 suffix?: string;
27 scorePassword?: boolean; 25 scorePassword?: boolean;
28 showPasswordToggle?: boolean; 26 showPasswordToggle?: boolean;
29 data: IData; 27 data?: IData;
30 inputClassName?: string; 28 inputClassName?: string;
31 onEnterKey?: Function; 29 onEnterKey?: Function;
32} 30}
@@ -37,42 +35,31 @@ interface IState {
37} 35}
38 36
39class InputComponent extends Component<IProps, IState> { 37class InputComponent extends Component<IProps, IState> {
40 static defaultProps = {
41 focus: false,
42 onChange: () => {},
43 onBlur: () => {},
44 onFocus: () => {},
45 scorePassword: false,
46 showLabel: true,
47 showPasswordToggle: false,
48 type: 'text',
49 disabled: false,
50 };
51
52 state = {
53 passwordScore: 0,
54 showPassword: false,
55 };
56
57 private inputRef = createRef<HTMLInputElement>(); 38 private inputRef = createRef<HTMLInputElement>();
58 39
59 componentDidMount() { 40 constructor(props: IProps) {
60 const { focus, data } = this.props; 41 super(props);
42
43 this.state = {
44 passwordScore: 0,
45 showPassword: false,
46 };
47 }
48
49 componentDidMount(): void {
50 const { focus, data = {} } = this.props;
61 51
62 if (this.inputRef && this.inputRef.current) { 52 if (this.inputRef && this.inputRef.current) {
63 if (focus) { 53 if (focus) {
64 this.inputRef.current.focus(); 54 this.inputRef.current.focus();
65 } 55 }
66 56
67 if (data) { 57 for (const key of Object.keys(data))
68 Object.keys(data).map( 58 this.inputRef.current!.dataset[key] = data[key];
69 key => (this.inputRef.current!.dataset[key] = data[key]),
70 );
71 }
72 } 59 }
73 } 60 }
74 61
75 onChange(e: React.ChangeEvent<HTMLInputElement>) { 62 onChange(e: React.ChangeEvent<HTMLInputElement>): void {
76 const { scorePassword, onChange } = this.props; 63 const { scorePassword, onChange } = this.props;
77 64
78 if (onChange) { 65 if (onChange) {
@@ -97,28 +84,28 @@ class InputComponent extends Component<IProps, IState> {
97 const { 84 const {
98 classes, 85 classes,
99 className, 86 className,
100 disabled,
101 error, 87 error,
102 id, 88 id,
103 inputClassName, 89 inputClassName,
104 label, 90 label,
105 prefix, 91 prefix,
106 scorePassword,
107 suffix, 92 suffix,
108 showLabel,
109 showPasswordToggle,
110 type,
111 value, 93 value,
112 name, 94 name,
113 placeholder, 95 placeholder,
114 spellCheck, 96 spellCheck,
115 onBlur,
116 onFocus,
117 min, 97 min,
118 max, 98 max,
119 step, 99 step,
120 required, 100 required,
121 noMargin, 101 noMargin,
102 onBlur = noop,
103 onFocus = noop,
104 scorePassword = false,
105 showLabel = true,
106 showPasswordToggle = false,
107 type = 'text',
108 disabled = false,
122 } = this.props; 109 } = this.props;
123 110
124 const { showPassword, passwordScore } = this.state; 111 const { showPassword, passwordScore } = this.state;
diff --git a/src/containers/auth/AuthLayoutContainer.tsx b/src/containers/auth/AuthLayoutContainer.tsx
index 6fc6713f1..6a1fed0d7 100644
--- a/src/containers/auth/AuthLayoutContainer.tsx
+++ b/src/containers/auth/AuthLayoutContainer.tsx
@@ -2,14 +2,15 @@ import { Component, ReactElement } from 'react';
2import { inject, observer } from 'mobx-react'; 2import { inject, observer } from 'mobx-react';
3import { ThemeProvider } from 'react-jss'; 3import { ThemeProvider } from 'react-jss';
4import { Outlet } from 'react-router-dom'; 4import { Outlet } from 'react-router-dom';
5
6import { StoresProps } from '../../@types/ferdium-components.types'; 5import { StoresProps } from '../../@types/ferdium-components.types';
7import AuthLayout from '../../components/auth/AuthLayout'; 6import AuthLayout from '../../components/auth/AuthLayout';
8import AppLoader from '../../components/ui/AppLoader'; 7import AppLoader from '../../components/ui/AppLoader';
9 8
10interface AuthLayoutContainerProps extends StoresProps {} 9interface IProps extends StoresProps {}
11 10
12class AuthLayoutContainer extends Component<AuthLayoutContainerProps> { 11@inject('stores', 'actions')
12@observer
13class AuthLayoutContainer extends Component<IProps> {
13 render(): ReactElement { 14 render(): ReactElement {
14 const { stores, actions } = this.props; 15 const { stores, actions } = this.props;
15 const { app, features, globalError, user } = stores; 16 const { app, features, globalError, user } = stores;
@@ -39,7 +40,6 @@ class AuthLayoutContainer extends Component<AuthLayoutContainerProps> {
39 <ThemeProvider theme={stores.ui.theme}> 40 <ThemeProvider theme={stores.ui.theme}>
40 <AuthLayout 41 <AuthLayout
41 error={globalError.response} 42 error={globalError.response}
42 pathname={stores.router.location.pathname}
43 isOnline={app.isOnline} 43 isOnline={app.isOnline}
44 isAPIHealthy={!app.healthCheckRequest.isError} 44 isAPIHealthy={!app.healthCheckRequest.isError}
45 retryHealthCheck={actions.app.healthCheck} 45 retryHealthCheck={actions.app.healthCheck}
@@ -58,4 +58,4 @@ class AuthLayoutContainer extends Component<AuthLayoutContainerProps> {
58 } 58 }
59} 59}
60 60
61export default inject('stores', 'actions')(observer(AuthLayoutContainer)); 61export default AuthLayoutContainer;
diff --git a/src/features/publishDebugInfo/Component.js b/src/features/publishDebugInfo/Component.tsx
index 27661d917..e265902dd 100644
--- a/src/features/publishDebugInfo/Component.js
+++ b/src/features/publishDebugInfo/Component.tsx
@@ -1,18 +1,15 @@
1import { inject, observer } from 'mobx-react'; 1import { inject, observer } from 'mobx-react';
2import PropTypes from 'prop-types'; 2import { Component, ReactElement } from 'react';
3import { Component } from 'react'; 3import { defineMessages, injectIntl, WrappedComponentProps } from 'react-intl';
4import { defineMessages, injectIntl } from 'react-intl'; 4import withStyles, { WithStylesProps } from 'react-jss';
5import injectSheet from 'react-jss'; 5import { StoresProps } from '../../@types/ferdium-components.types';
6import { state as ModalState } from './store'; 6import { state as ModalState } from './store';
7
8import { H1 } from '../../components/ui/headline'; 7import { H1 } from '../../components/ui/headline';
9import { sendAuthRequest } from '../../api/utils/auth'; 8import { sendAuthRequest } from '../../api/utils/auth';
10import Button from '../../components/ui/button'; 9import Button from '../../components/ui/button';
11import Input from '../../components/ui/input/index'; 10import Input from '../../components/ui/input/index';
12import Modal from '../../components/ui/Modal'; 11import Modal from '../../components/ui/Modal';
13import { DEBUG_API } from '../../config'; 12import { DEBUG_API } from '../../config';
14import AppStore from '../../stores/AppStore';
15import ServicesStore from '../../stores/ServicesStore';
16 13
17const debug = require('../../preload-safe-debug')( 14const debug = require('../../preload-safe-debug')(
18 'Ferdium:feature:publishDebugInfo', 15 'Ferdium:feature:publishDebugInfo',
@@ -78,30 +75,47 @@ const styles = theme => ({
78 }, 75 },
79}); 76});
80 77
81class PublishDebugLogModal extends Component { 78interface IProps
82 state = { 79 extends Partial<StoresProps>,
83 log: null, 80 WithStylesProps<typeof styles>,
84 error: false, 81 WrappedComponentProps {}
85 isSendingLog: false, 82
86 }; 83interface IState {
84 log: null;
85 error: boolean;
86 isSendingLogs: boolean;
87}
88
89@inject('stores', 'actions')
90@observer
91class PublishDebugLogModal extends Component<IProps, IState> {
92 constructor(props: IProps) {
93 super(props);
94
95 this.state = {
96 log: null,
97 error: false,
98 isSendingLogs: false,
99 };
100 }
87 101
88 // Close this modal 102 // Close this modal
89 close() { 103 close(): void {
90 ModalState.isModalVisible = false; 104 ModalState.isModalVisible = false;
91 this.setState({ 105 this.setState({
92 log: null, 106 log: null,
93 error: false, 107 error: false,
94 isSendingLog: false, 108 isSendingLogs: false,
95 }); 109 });
96 } 110 }
97 111
98 async publishDebugInfo() { 112 async publishDebugInfo(): Promise<void> {
99 debug('debugInfo: starting publish'); 113 debug('debugInfo: starting publish');
100 this.setState({ 114 this.setState({
101 isSendingLog: true, 115 isSendingLogs: true,
102 }); 116 });
103 117
104 const debugInfo = JSON.stringify(this.props.stores.app.debugInfo); 118 const debugInfo = JSON.stringify(this.props.stores?.app?.debugInfo);
105 119
106 const request = await sendAuthRequest( 120 const request = await sendAuthRequest(
107 `${DEBUG_API}/create`, 121 `${DEBUG_API}/create`,
@@ -118,31 +132,21 @@ class PublishDebugLogModal extends Component {
118 if (request.status === 200) { 132 if (request.status === 200) {
119 const response = await request.json(); 133 const response = await request.json();
120 if (response.id) { 134 if (response.id) {
121 this.setState({ 135 this.setState({ log: response.id });
122 log: response.id,
123 });
124 } else { 136 } else {
125 this.setState({ 137 this.setState({ error: true });
126 error: true,
127 });
128 } 138 }
129 } else { 139 } else {
130 this.setState({ 140 this.setState({ error: true });
131 error: true,
132 });
133 } 141 }
134 142
135 debug('debugInfo: finished publishing'); 143 debug('debugInfo: finished publishing');
136 } 144 }
137 145
138 render() { 146 render(): ReactElement {
139 const { isModalVisible } = ModalState; 147 const { isModalVisible } = ModalState;
140 148 const { classes, intl } = this.props;
141 const { classes } = this.props; 149 const { log, error, isSendingLogs } = this.state;
142
143 const { log, error, isSendingLog } = this.state;
144
145 const { intl } = this.props;
146 150
147 return ( 151 return (
148 <Modal 152 <Modal
@@ -159,18 +163,16 @@ class PublishDebugLogModal extends Component {
159 <p className={classes.info}> 163 <p className={classes.info}>
160 {intl.formatMessage(messages.published)} 164 {intl.formatMessage(messages.published)}
161 </p> 165 </p>
162 <Input showLabel={false} value={`${DEBUG_API}/${log}`} readonly /> 166 {/* TODO - [TS DEBT] need to check if <Input/> take readOnly and use it */}
167 <Input showLabel={false} value={`${DEBUG_API}/${log}`} readOnly />
163 </> 168 </>
164 )} 169 )}
165
166 {error && ( 170 {error && (
167 <p className={classes.info}>{intl.formatMessage(messages.error)}</p> 171 <p className={classes.info}>{intl.formatMessage(messages.error)}</p>
168 )} 172 )}
169
170 {!log && !error && ( 173 {!log && !error && (
171 <> 174 <>
172 <p className={classes.info}>{intl.formatMessage(messages.info)}</p> 175 <p className={classes.info}>{intl.formatMessage(messages.info)}</p>
173
174 <a 176 <a
175 href={`${DEBUG_API}/privacy.html`} 177 href={`${DEBUG_API}/privacy.html`}
176 target="_blank" 178 target="_blank"
@@ -187,13 +189,12 @@ class PublishDebugLogModal extends Component {
187 > 189 >
188 {intl.formatMessage(messages.terms)} 190 {intl.formatMessage(messages.terms)}
189 </a> 191 </a>
190
191 <Button 192 <Button
192 type="button" 193 type="button"
193 label={intl.formatMessage(messages.publish)} 194 label={intl.formatMessage(messages.publish)}
194 className={classes.button} 195 className={classes.button}
195 onClick={() => this.publishDebugInfo()} 196 onClick={() => this.publishDebugInfo()}
196 disabled={isSendingLog} 197 disabled={isSendingLogs}
197 /> 198 />
198 </> 199 </>
199 )} 200 )}
@@ -202,18 +203,6 @@ class PublishDebugLogModal extends Component {
202 } 203 }
203} 204}
204 205
205PublishDebugLogModal.propTypes = {
206 stores: PropTypes.shape({
207 app: PropTypes.instanceOf(AppStore).isRequired,
208 }).isRequired,
209 actions: PropTypes.shape({
210 service: PropTypes.instanceOf(ServicesStore).isRequired,
211 }).isRequired,
212 classes: PropTypes.object.isRequired,
213};
214
215export default injectIntl( 206export default injectIntl(
216 injectSheet(styles, { injectTheme: true })( 207 withStyles(styles, { injectTheme: true })(PublishDebugLogModal),
217 inject('stores', 'actions')(observer(PublishDebugLogModal)),
218 ),
219); 208);
diff --git a/src/features/publishDebugInfo/index.ts b/src/features/publishDebugInfo/index.ts
index 80714a104..cbbdbc594 100644
--- a/src/features/publishDebugInfo/index.ts
+++ b/src/features/publishDebugInfo/index.ts
@@ -1,21 +1,17 @@
1import { state as ModalState } from './store'; 1import { state } from './store';
2 2
3export { default as Component } from './Component'; 3export { default as Component } from './Component';
4 4
5const state = ModalState;
6const debug = require('../../preload-safe-debug')( 5const debug = require('../../preload-safe-debug')(
7 'Ferdium:feature:publishDebugInfo', 6 'Ferdium:feature:publishDebugInfo',
8); 7);
9 8
10export default function initialize() { 9export default function initialize(): void {
11 debug('Initialize publishDebugInfo feature'); 10 debug('Initialize publishDebugInfo feature');
12 11
13 function showModal() { 12 const showModal = (): void => {
14 state.isModalVisible = true; 13 state.isModalVisible = true;
15 }
16
17 window['ferdium'].features.publishDebugInfo = {
18 state,
19 showModal,
20 }; 14 };
15
16 window['ferdium'].features.publishDebugInfo = { state, showModal };
21} 17}
diff --git a/src/routes.tsx b/src/routes.tsx
index 478d3dfe8..8150d135e 100644
--- a/src/routes.tsx
+++ b/src/routes.tsx
@@ -6,7 +6,7 @@ import {
6 Routes, 6 Routes,
7 unstable_HistoryRouter as HistoryRouter, 7 unstable_HistoryRouter as HistoryRouter,
8} from 'react-router-dom'; 8} from 'react-router-dom';
9 9import { HashHistory } from 'history';
10import AppLayoutContainer from './containers/layout/AppLayoutContainer'; 10import AppLayoutContainer from './containers/layout/AppLayoutContainer';
11import SettingsWindow from './containers/settings/SettingsWindow'; 11import SettingsWindow from './containers/settings/SettingsWindow';
12import ReleaseNotesWindow from './containers/settings/ReleaseNotesWindow'; 12import ReleaseNotesWindow from './containers/settings/ReleaseNotesWindow';
@@ -33,25 +33,19 @@ import AuthLayoutContainer from './containers/auth/AuthLayoutContainer';
33import WorkspacesScreen from './features/workspaces/containers/WorkspacesScreen'; 33import WorkspacesScreen from './features/workspaces/containers/WorkspacesScreen';
34import EditWorkspaceScreen from './features/workspaces/containers/EditWorkspaceScreen'; 34import EditWorkspaceScreen from './features/workspaces/containers/EditWorkspaceScreen';
35import { WORKSPACES_ROUTES } from './features/workspaces/constants'; 35import { WORKSPACES_ROUTES } from './features/workspaces/constants';
36import { Actions } from './actions/lib/actions'; 36import { StoresProps } from './@types/ferdium-components.types';
37import { RealStores } from './stores';
38 37
39type Props = { 38interface IProps extends StoresProps {
40 stores: RealStores; 39 history: HashHistory;
41 actions: Actions; 40}
42 history: any;
43};
44 41
45class FerdiumRoutes extends Component<Props> { 42@inject('stores', 'actions')
43@observer
44class FerdiumRoutes extends Component<IProps> {
46 render(): ReactElement { 45 render(): ReactElement {
47 const { history } = this.props; 46 const { history, stores, actions } = this.props;
48 const routeProps = { 47 const routeProps: StoresProps = { stores, actions };
49 stores: this.props.stores, 48 const errorProps = { error: this.props.stores.globalError.error || {} };
50 actions: this.props.actions,
51 };
52 const errorProps = {
53 error: this.props.stores.globalError.error || {},
54 };
55 49
56 return ( 50 return (
57 <HistoryRouter history={history}> 51 <HistoryRouter history={history}>
@@ -185,4 +179,4 @@ class FerdiumRoutes extends Component<Props> {
185 } 179 }
186} 180}
187 181
188export default inject('stores', 'actions')(observer(FerdiumRoutes)); 182export default FerdiumRoutes;