Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[DRAFT] Diagnostic Modal #1366

Draft
wants to merge 2 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions apps/reactotron-app/src/renderer/RootModals.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,11 @@ import {
SubscriptionAddModal,
ReactotronContext,
StateContext,
DiagnosticModal,
} from "reactotron-core-ui"
import configStore from "./config"
import StandaloneContext from "./contexts/Standalone"
import { getServerStatusData } from "./components/SideBar/Sidebar"

function RootModals() {
const {
Expand All @@ -17,8 +21,14 @@ function RootModals() {
// Subscription Modal
isSubscriptionModalOpen,
closeSubscriptionModal,
// Diagnostic Modal
isDiagnosticModalOpen,
closeDiagnosticModal,
} = useContext(ReactotronContext)
const { addSubscription } = useContext(StateContext)
const { serverStatus } = useContext(StandaloneContext)
const { serverStatusText } = getServerStatusData(serverStatus)


const dispatchAction = (action: any) => {
sendCommand("state.action.dispatch", { action })
Expand Down Expand Up @@ -46,6 +56,17 @@ function RootModals() {
addSubscription(path)
}}
/>
<DiagnosticModal
isOpen={isDiagnosticModalOpen}
onClose={() => {
closeDiagnosticModal()
}}
port={configStore.get("serverPort") as string}
serverStatusText={serverStatusText}
onRefresh={() => {
window.location.reload()
}}
/>
</>
)
}
Expand Down
42 changes: 22 additions & 20 deletions apps/reactotron-app/src/renderer/components/SideBar/Sidebar.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React from "react"
import React, { useContext } from "react"
import {
MdReorder,
MdAssignment,
Expand All @@ -14,6 +14,7 @@ import styled from "styled-components"
import SideBarButton from "../SideBarButton"
import { reactotronLogo } from "../../images"
import { ServerStatus } from "../../contexts/Standalone/useStandalone"
import { ReactotronContext } from "reactotron-core-ui"

interface SideBarContainerProps {
$isOpen: boolean
Expand All @@ -33,26 +34,27 @@ const Spacer = styled.div`
flex: 1;
`

function SideBar({ isOpen, serverStatus }: { isOpen: boolean; serverStatus: ServerStatus }) {
let serverIcon = MdMobiledataOff
let iconColor
let serverText = "Stopped"
export function getServerStatusData(serverStatus: ServerStatus) {
let serverStatusIcon = MdMobiledataOff
let serverStatusColor
let serverStatusText = "Stopped"
if (serverStatus === "started") {
serverIcon = MdOutlineMobileFriendly
serverText = "Running"
serverStatusIcon = MdOutlineMobileFriendly
serverStatusText = "Running"
}
if (serverStatus === "portUnavailable") {
serverIcon = MdWarning
iconColor = "yellow"
serverText = "Port 9090 unavailable"
serverStatusIcon = MdWarning
serverStatusColor = "yellow"
serverStatusText = "Port 9090 unavailable"
}

const retryConnection = () => {
if (serverStatus === "portUnavailable") {
// TODO: Reconnect more elegantly than forcing a reload
window.location.reload()
}
}
return { serverStatusIcon, serverStatusText,serverStatusColor }
}

function SideBar({ isOpen, serverStatus }: { isOpen: boolean; serverStatus: ServerStatus }) {
const {openDiagnosticModal} = useContext(ReactotronContext)

const { serverStatusColor, serverStatusIcon, serverStatusText } = getServerStatusData(serverStatus)

return (
<SideBarContainer $isOpen={isOpen}>
Expand All @@ -75,11 +77,11 @@ function SideBar({ isOpen, serverStatus }: { isOpen: boolean; serverStatus: Serv
<Spacer />

<SideBarButton
icon={serverIcon}
icon={serverStatusIcon}
path="#"
onPress={retryConnection}
text={serverText}
iconColor={iconColor}
onPress={openDiagnosticModal}
text={serverStatusText}
iconColor={serverStatusColor}
/>

<SideBarButton icon={MdLiveHelp} path="/help" text="Help" hideTopBar />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@ function buildContextValues({ addCommandListener = null } = {}) {
isSubscriptionModalOpen: false,
openSubscriptionModal: jest.fn(),
closeSubscriptionModal: jest.fn(),
isDiagnosticModalOpen: false,
openDiagnosticModal: jest.fn(),
closeDiagnosticModal: jest.fn(),
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@ function buildContextValues({ addCommandListener = null } = {}) {
isSubscriptionModalOpen: false,
openSubscriptionModal: jest.fn(),
closeSubscriptionModal: jest.fn(),
isDiagnosticModalOpen: false,
openDiagnosticModal: jest.fn(),
closeDiagnosticModal: jest.fn(),
}
}

Expand Down
15 changes: 15 additions & 0 deletions lib/reactotron-core-ui/src/contexts/Reactotron/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,12 @@ interface ContextProps extends Props {
isSubscriptionModalOpen: boolean
openSubscriptionModal: () => void
closeSubscriptionModal: () => void

// Diagnostic Modal
isDiagnosticModalOpen: boolean
openDiagnosticModal: () => void
closeDiagnosticModal: () => void

}

const ReactotronContext = React.createContext<ContextProps>({
Expand All @@ -39,6 +45,9 @@ const ReactotronContext = React.createContext<ContextProps>({
isSubscriptionModalOpen: false,
openSubscriptionModal: null,
closeSubscriptionModal: null,
isDiagnosticModalOpen: false,
openDiagnosticModal: null,
closeDiagnosticModal: null,
})

const Provider: FunctionComponent<React.PropsWithChildren<Props>> = ({
Expand All @@ -56,6 +65,9 @@ const Provider: FunctionComponent<React.PropsWithChildren<Props>> = ({
isSubscriptionModalOpen,
openSubscriptionModal,
closeSubscriptionModal,
isDiagnosticModalOpen,
openDiagnosticModal,
closeDiagnosticModal,
} = useReactotron()

return (
Expand All @@ -72,6 +84,9 @@ const Provider: FunctionComponent<React.PropsWithChildren<Props>> = ({
isSubscriptionModalOpen,
openSubscriptionModal,
closeSubscriptionModal,
isDiagnosticModalOpen,
openDiagnosticModal,
closeDiagnosticModal,
}}
>
{children}
Expand Down
29 changes: 29 additions & 0 deletions lib/reactotron-core-ui/src/contexts/Reactotron/useReactotron.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,16 @@ interface ReactotronState {
isDispatchModalOpen: boolean
dispatchModalInitialAction: string
isSubscriptionModalOpen: boolean
isDiagnosticModalOpen: boolean
}

enum ReactotronActionType {
DispatchModalOpen = "DISPATCH_OPEN",
DispatchModalClose = "DISPATCH_CLOSE",
SubscriptionModalOpen = "SUBSCRIPTION_OPEN",
SubscriptionModalClose = "SUBSCRIPTION_CLOSE",
DiagnosticModalOpen = "DIAGNOSTIC_OPEN",
DiagnosticModalClose = "DIAGNOSTIC_CLOSE",
}

interface ReactotronAction {
Expand Down Expand Up @@ -41,6 +44,16 @@ function reactotronReducer(state: ReactotronState, action: ReactotronAction) {
...state,
isSubscriptionModalOpen: false,
}
case ReactotronActionType.DiagnosticModalOpen:
return {
...state,
isDiagnosticModalOpen: true,
}
case ReactotronActionType.DiagnosticModalClose:
return {
...state,
isDiagnosticModalOpen: false,
}
default:
return state
}
Expand All @@ -51,6 +64,7 @@ function useReactotron() {
isDispatchModalOpen: false,
dispatchModalInitialAction: "",
isSubscriptionModalOpen: false,
isDiagnosticModalOpen: false,
})

const openDispatchModal = useCallback((intiialAction: string) => {
Expand Down Expand Up @@ -78,14 +92,29 @@ function useReactotron() {
})
}, [])

const openDiagnosticModal = useCallback(() => {
dispatch({
type: ReactotronActionType.DiagnosticModalOpen,
})
}, [])

const closeDiagnosticModal = useCallback(() => {
dispatch({
type: ReactotronActionType.DiagnosticModalClose,
})
}, [])

return {
isDispatchModalOpen: state.isDispatchModalOpen,
isDiagnosticModalOpen: state.isDiagnosticModalOpen,
dispatchModalInitialAction: state.dispatchModalInitialAction,
openDispatchModal,
closeDispatchModal,
isSubscriptionModalOpen: state.isSubscriptionModalOpen,
openSubscriptionModal,
closeSubscriptionModal,
openDiagnosticModal,
closeDiagnosticModal
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@ function buildContextValues({ addCommandListener = null } = {}) {
isSubscriptionModalOpen: false,
openSubscriptionModal: jest.fn(),
closeSubscriptionModal: jest.fn(),
isDiagnosticModalOpen: false,
openDiagnosticModal: jest.fn(),
closeDiagnosticModal: jest.fn(),
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@ function buildContextValues({ addCommandListener = null } = {}) {
isSubscriptionModalOpen: false,
openSubscriptionModal: jest.fn(),
closeSubscriptionModal: jest.fn(),
isDiagnosticModalOpen: false,
openDiagnosticModal: jest.fn(),
closeDiagnosticModal: jest.fn(),
}
}

Expand Down
2 changes: 2 additions & 0 deletions lib/reactotron-core-ui/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import DispatchActionModal from "./modals/DispatchActionModal"
import SnapshotRenameModal from "./modals/SnapshotRenameModal"
import SubscriptionAddModal from "./modals/SubscriptionAddModal"
import TimelineFilterModal from "./modals/TimelineFilterModal"
import DiagnosticModal from "./modals/DiagnosticModal"

// Timeline Commands
import timelineCommandResolver from "./timelineCommands"
Expand All @@ -50,6 +51,7 @@ export {
SnapshotRenameModal,
SubscriptionAddModal,
TimelineFilterModal,
DiagnosticModal,
Timestamp,
TreeView,
repairSerialization,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
/* eslint-disable @typescript-eslint/no-empty-function */
import React from "react"

import DiagnosticModal from "./index"

export default {
title: "Diagnostic Modal",
}

export const Default = () => (
<DiagnosticModal isOpen onClose={() => {}} onRefresh={() => console.info("Refreshed")} port={"9090"} serverStatusText="started" />
)
68 changes: 68 additions & 0 deletions lib/reactotron-core-ui/src/modals/DiagnosticModal/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
import React, { FunctionComponent, useCallback, useEffect } from "react"
import styled from "styled-components"

import Modal, { Keystroke, KeystrokeContainer } from "../../components/Modal"


const Heading = styled.div`
font-size: 18px;
margin: 18px 0 10px;
padding-bottom: 2px;
border-bottom: 1px solid ${(props) => props.theme.highlight};
color: ${(props) => props.theme.foregroundLight};
`

const Content = styled.div`
margin-top: 10px;
color: ${(props) => props.theme.string};
`

interface Props {
isOpen: boolean
onClose: () => void
port: string
serverStatusText: string
onRefresh: () => void
}

const DiagnosticModal: FunctionComponent<Props> = ({ isOpen, onClose, port, serverStatusText, onRefresh }) => {

const handleClose = useCallback(() => {
onClose()
}, [onClose])

useEffect(() => {
function onKeyPress(e: KeyboardEvent) {
if (e.key === "Enter") {
onRefresh ()
}
}

addEventListener("keypress", onKeyPress);

return () => {
removeEventListener("keypress", onKeyPress);
}
}, [onRefresh])

return (
<Modal
title="Diagnostics"
isOpen={isOpen}
onClose={handleClose}
additionalKeystrokes={
<KeystrokeContainer >
<Keystroke>ENTER</Keystroke> Refresh Connection
</KeystrokeContainer>
}
>
<Heading>Port</Heading>
<Content>{port || "n/a"}</Content>

<Heading>Server Status</Heading>
<Content>{serverStatusText}</Content>
</Modal>
)
}

export default DiagnosticModal