Skip to content

[DRAFT] Diagnostic Modal #1366

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
wants to merge 2 commits into
base: master
Choose a base branch
from
Draft
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
@@ -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 {
@@ -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 })
@@ -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()
}}
/>
</>
)
}
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,
@@ -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
@@ -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}>
@@ -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 />
Original file line number Diff line number Diff line change
@@ -20,6 +20,9 @@ function buildContextValues({ addCommandListener = null } = {}) {
isSubscriptionModalOpen: false,
openSubscriptionModal: jest.fn(),
closeSubscriptionModal: jest.fn(),
isDiagnosticModalOpen: false,
openDiagnosticModal: jest.fn(),
closeDiagnosticModal: jest.fn(),
}
}

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

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

return (
@@ -72,6 +84,9 @@ const Provider: FunctionComponent<React.PropsWithChildren<Props>> = ({
isSubscriptionModalOpen,
openSubscriptionModal,
closeSubscriptionModal,
isDiagnosticModalOpen,
openDiagnosticModal,
closeDiagnosticModal,
}}
>
{children}
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
@@ -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 {
@@ -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
}
@@ -51,6 +64,7 @@ function useReactotron() {
isDispatchModalOpen: false,
dispatchModalInitialAction: "",
isSubscriptionModalOpen: false,
isDiagnosticModalOpen: false,
})

const openDispatchModal = useCallback((intiialAction: string) => {
@@ -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
}
}

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

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

2 changes: 2 additions & 0 deletions lib/reactotron-core-ui/src/index.ts
Original file line number Diff line number Diff line change
@@ -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"
@@ -50,6 +51,7 @@ export {
SnapshotRenameModal,
SubscriptionAddModal,
TimelineFilterModal,
DiagnosticModal,
Timestamp,
TreeView,
repairSerialization,
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