From e648f158202d067aa02822b83bd8437ad1a658bf Mon Sep 17 00:00:00 2001 From: Mark Kim <103070941+marckong@users.noreply.github.com> Date: Mon, 25 Jul 2022 10:35:25 -0400 Subject: [PATCH] refactor: convert settings-modal to functional (#4991) * add modal fc conversion * clean up * Update packages/insomnia/src/ui/components/modals/settings-modal.tsx Co-authored-by: James Gatz * Update packages/insomnia/src/ui/components/modals/settings-modal.tsx Co-authored-by: James Gatz * Update packages/insomnia/src/ui/components/modals/settings-modal.tsx Co-authored-by: James Gatz * add requested changes Co-authored-by: James Gatz --- .../src/ui/components/modals/index.ts | 10 +- .../ui/components/modals/settings-modal.tsx | 205 ++++++++---------- .../insomnia/src/ui/components/wrapper.tsx | 2 +- 3 files changed, 95 insertions(+), 122 deletions(-) diff --git a/packages/insomnia/src/ui/components/modals/index.ts b/packages/insomnia/src/ui/components/modals/index.ts index c12ba7b49..f6dfa74e0 100644 --- a/packages/insomnia/src/ui/components/modals/index.ts +++ b/packages/insomnia/src/ui/components/modals/index.ts @@ -4,14 +4,18 @@ import { ErrorModal, ErrorModalOptions } from './error-modal'; import { PromptModal, PromptModalOptions } from './prompt-modal'; const modals: Record = {}; +export interface ModalHandle { + hide(): void; + show(): void; +} -export function registerModal(instance: any) { +export function registerModal(instance: any, modalName?: string) { if (instance === null) { // Modal was unmounted return; } - modals[instance.constructor.name] = instance; + modals[modalName ?? instance.constructor.name] = instance; } export function showModal(modalCls: any, ...args: any[]) { @@ -43,7 +47,7 @@ export function hideAllModals() { } function _getModal(modalCls: any) { - const m = modals[modalCls.name || modalCls.WrappedComponent?.name]; + const m = modals[modalCls.name || modalCls.WrappedComponent?.name || modalCls.displayName]; if (!m) { throw new Error('Modal was not registered with the app'); diff --git a/packages/insomnia/src/ui/components/modals/settings-modal.tsx b/packages/insomnia/src/ui/components/modals/settings-modal.tsx index 24ff0733b..05be5d354 100644 --- a/packages/insomnia/src/ui/components/modals/settings-modal.tsx +++ b/packages/insomnia/src/ui/components/modals/settings-modal.tsx @@ -1,16 +1,14 @@ -import { autoBindMethodsForReact } from 'class-autobind-decorator'; import { HotKeyRegistry } from 'insomnia-common'; -import React, { PureComponent } from 'react'; -import { connect } from 'react-redux'; +import React, { forwardRef, useEffect, useImperativeHandle, useRef, useState } from 'react'; +import { useSelector } from 'react-redux'; import { Tab, TabList, TabPanel, Tabs } from 'react-tabs'; import * as session from '../../../account/session'; -import { AUTOBIND_CFG, getAppVersion, getProductName } from '../../../common/constants'; +import { getAppVersion, getProductName } from '../../../common/constants'; import * as models from '../../../models/index'; -import { RootState } from '../../redux/modules'; import { selectSettings } from '../../redux/selectors'; import { Button } from '../base/button'; -import { Modal } from '../base/modal'; +import { Modal, ModalProps } from '../base/modal'; import { ModalBody } from '../base/modal-body'; import { ModalHeader } from '../base/modal-header'; import { Account } from '../settings/account'; @@ -19,128 +17,99 @@ import { ImportExport } from '../settings/import-export'; import { Plugins } from '../settings/plugins'; import { Shortcuts } from '../settings/shortcuts'; import { ThemePanel } from '../settings/theme-panel'; -import { showModal } from './index'; +import { ModalHandle, registerModal, showModal } from './index'; +export interface SettingsModalHandle extends ModalHandle { + show(): void; + show(currentTabIndex: number): void; +} export const TAB_INDEX_EXPORT = 1; export const TAB_INDEX_SHORTCUTS = 3; export const TAB_INDEX_THEMES = 2; export const TAB_INDEX_PLUGINS = 5; +export const SETTINGS_MODAL_DISPLAY_NAME = 'SettingsModal'; +export const SettingsModal = forwardRef((props, ref) => { + const settings = useSelector(selectSettings); + const [currentTabIndex, setCurrentTabIndex] = useState(null); + const modalRef = useRef(null); + const email = session.isLoggedIn() ? session.getFullName() : null; -type ReduxProps = ReturnType; - -interface Props extends ReduxProps { -} - -interface State { - currentTabIndex: number | null; -} - -@autoBindMethodsForReact(AUTOBIND_CFG) -export class UnconnectedSettingsModal extends PureComponent { - state: State = { - currentTabIndex: null, - }; - - modal: Modal | null = null; - - _setModalRef(modal: Modal) { - this.modal = modal; - } - - async _handleUpdateKeyBindings(hotKeyRegistry: HotKeyRegistry) { - await models.settings.update(this.props.settings, { + const handleUpdateKeyBindings = async (hotKeyRegistry: HotKeyRegistry) => { + await models.settings.update(settings, { hotKeyRegistry, }); - } + }; - show(currentTabIndex = 0) { - if (typeof currentTabIndex !== 'number') { - currentTabIndex = 0; - } + useEffect(() => { + registerModal(modalRef.current, SETTINGS_MODAL_DISPLAY_NAME); + }, []); - this.setState({ - currentTabIndex, - }); - this.modal?.show(); - } + useImperativeHandle(ref, () => ({ + hide(): void { + modalRef.current?.hide(); + }, + show(currentTabIndex = 0): void { + const tabIndex = typeof currentTabIndex !== 'number' ? 0 : currentTabIndex; + setCurrentTabIndex(tabIndex); + modalRef.current?.show(); + }, + }), []); - hide() { - this.modal?.hide(); - } - - render() { - const { settings } = this.props; - const { currentTabIndex } = this.state; - const email = session.isLoggedIn() ? session.getFullName() : null; - return ( - - - {getProductName()} Preferences - + return ( + + + {getProductName()} Preferences +   –  v{getAppVersion()} - {email ? ` – ${email}` : null} - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ); - } -} - -export const showSettingsModal = () => showModal(SettingsModal); - -const mapStateToProps = (state: RootState) => ({ - settings: selectSettings(state), + {email ? ` – ${email}` : null} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + modalRef.current?.hide()}/> + + + + + + + + + + + + + + + + + ); }); - -export const SettingsModal = connect( - mapStateToProps, - null, - null, - { forwardRef: true }, -)(UnconnectedSettingsModal); +SettingsModal.displayName = SETTINGS_MODAL_DISPLAY_NAME; +export const showSettingsModal = () => showModal(SettingsModal); diff --git a/packages/insomnia/src/ui/components/wrapper.tsx b/packages/insomnia/src/ui/components/wrapper.tsx index 919bfb434..e7be504f1 100644 --- a/packages/insomnia/src/ui/components/wrapper.tsx +++ b/packages/insomnia/src/ui/components/wrapper.tsx @@ -513,7 +513,7 @@ export class Wrapper extends PureComponent { environmentId={activeEnvironment ? activeEnvironment._id : 'n/a'} /> - +