From 0bdb73e344f7ac46b861b921978fae7fea156ed9 Mon Sep 17 00:00:00 2001 From: Dmitrii Derepko Date: Mon, 4 Sep 2023 16:36:27 +0300 Subject: [PATCH 1/7] Fix notifications --- packages/yii-dev-panel-sdk/src/Component/Notifications.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/yii-dev-panel-sdk/src/Component/Notifications.tsx b/packages/yii-dev-panel-sdk/src/Component/Notifications.tsx index d579aab..15fe41f 100644 --- a/packages/yii-dev-panel-sdk/src/Component/Notifications.tsx +++ b/packages/yii-dev-panel-sdk/src/Component/Notifications.tsx @@ -20,7 +20,7 @@ export const NotificationsSlice = createSlice({ removeNotification(state, action: PayloadAction) { state.notifications[action.payload].shown = false; }, - addNotification: (state, action: PayloadAction>) => { + addNotification: (state, action: PayloadAction>) => { state.notifications = [...state.notifications, {...action.payload, shown: true}]; }, }, From 152df88fbb36f17e32ab098a78410a05ea4e34b3 Mon Sep 17 00:00:00 2001 From: Dmitrii Derepko Date: Thu, 7 Sep 2023 19:45:22 +0300 Subject: [PATCH 2/7] Add dev-server --- .../src/Component/ServerSentEventsObserver.ts | 2 +- .../src/Component/useDevServerEvents.ts | 34 ++++++++++++ .../src/Module/DevServer/Context/Context.tsx | 29 ++++++++++ .../src/Module/DevServer/Pages/Layout.tsx | 55 +++++++++++++++++++ .../src/Module/DevServer/Pages/index.ts | 1 + .../yii-dev-panel/src/Module/DevServer/api.ts | 15 +++++ .../src/Module/DevServer/index.ts | 10 ++++ .../src/Module/DevServer/router.tsx | 9 +++ packages/yii-dev-panel/src/modules.ts | 11 +++- 9 files changed, 164 insertions(+), 2 deletions(-) create mode 100644 packages/yii-dev-panel-sdk/src/Component/useDevServerEvents.ts create mode 100644 packages/yii-dev-panel/src/Module/DevServer/Context/Context.tsx create mode 100644 packages/yii-dev-panel/src/Module/DevServer/Pages/Layout.tsx create mode 100644 packages/yii-dev-panel/src/Module/DevServer/Pages/index.ts create mode 100644 packages/yii-dev-panel/src/Module/DevServer/api.ts create mode 100644 packages/yii-dev-panel/src/Module/DevServer/index.ts create mode 100644 packages/yii-dev-panel/src/Module/DevServer/router.tsx diff --git a/packages/yii-dev-panel-sdk/src/Component/ServerSentEventsObserver.ts b/packages/yii-dev-panel-sdk/src/Component/ServerSentEventsObserver.ts index 5c1bdd1..e85a107 100644 --- a/packages/yii-dev-panel-sdk/src/Component/ServerSentEventsObserver.ts +++ b/packages/yii-dev-panel-sdk/src/Component/ServerSentEventsObserver.ts @@ -1,7 +1,7 @@ import {Config} from '@yiisoft/yii-dev-panel-sdk/Config'; // TODO support custom events and decode payload to object -class ServerSentEvents { +export class ServerSentEvents { private eventSource: EventSource = null; private listeners: ((event: MessageEvent) => void)[] = []; constructor(private url: string) {} diff --git a/packages/yii-dev-panel-sdk/src/Component/useDevServerEvents.ts b/packages/yii-dev-panel-sdk/src/Component/useDevServerEvents.ts new file mode 100644 index 0000000..eb1dfbe --- /dev/null +++ b/packages/yii-dev-panel-sdk/src/Component/useDevServerEvents.ts @@ -0,0 +1,34 @@ +import {ServerSentEventsObserver} from '@yiisoft/yii-dev-panel-sdk/Component/ServerSentEventsObserver'; +import {useEffect, useRef} from 'react'; + +type DebugUpdatedType = { + type: EventTypesEnum.DebugUpdated; + payload: {}; +}; + +export enum EventTypesEnum { + DebugUpdated = 'debug-updated', +} + +export type EventTypes = DebugUpdatedType; + +export const useDevServerEvents = (onMessage: (event: MessageEvent) => void, subscribe = true) => { + const prevOnMessage = useRef(onMessage); + + useEffect(() => { + if (prevOnMessage.current) { + ServerSentEventsObserver.unsubscribe(prevOnMessage.current); + } + if (!subscribe) { + return; + } + + ServerSentEventsObserver.subscribe(onMessage); + prevOnMessage.current = onMessage; + + return () => { + ServerSentEventsObserver.unsubscribe(onMessage); + ServerSentEventsObserver.close(); + }; + }, [onMessage, subscribe]); +}; diff --git a/packages/yii-dev-panel/src/Module/DevServer/Context/Context.tsx b/packages/yii-dev-panel/src/Module/DevServer/Context/Context.tsx new file mode 100644 index 0000000..d692682 --- /dev/null +++ b/packages/yii-dev-panel/src/Module/DevServer/Context/Context.tsx @@ -0,0 +1,29 @@ +import {createSlice} from '@reduxjs/toolkit'; +import {useSelector} from 'react-redux'; + +export const framesSlice = createSlice({ + name: 'store.frames2', + initialState: { + frames: {} as Record, + }, + reducers: { + addFrame: (state, action) => { + state.frames = { + ...state.frames, + [action.payload]: action.payload, + }; + }, + updateFrame: (state, action) => { + state.frames = action.payload; + }, + deleteFrame: (state, action) => { + const frames = Object.entries(state.frames).filter(([name, url]) => name != action.payload); + state.frames = Object.fromEntries(frames); + }, + }, +}); + +export const {addFrame, updateFrame, deleteFrame} = framesSlice.actions; + +type State = {[framesSlice.name]: ReturnType}; +export const useDevServerEntries = () => useSelector((state: State) => state[framesSlice.name].frames); diff --git a/packages/yii-dev-panel/src/Module/DevServer/Pages/Layout.tsx b/packages/yii-dev-panel/src/Module/DevServer/Pages/Layout.tsx new file mode 100644 index 0000000..78fa815 --- /dev/null +++ b/packages/yii-dev-panel/src/Module/DevServer/Pages/Layout.tsx @@ -0,0 +1,55 @@ +import {ServerSentEvents} from '@yiisoft/yii-dev-panel-sdk/Component/ServerSentEventsObserver'; +import {Config} from '@yiisoft/yii-dev-panel-sdk/Config'; +import {useEffect, useRef, useState} from 'react'; + +const DevServerObserver = new ServerSentEvents(Config.backendUrl + '/debug/api/dev'); + +type DebugUpdatedType = { + type: EventTypesEnum.DebugUpdated; + payload: {}; +}; + +export enum EventTypesEnum { + DebugUpdated = 'debug-updated', +} + +export type EventTypes = DebugUpdatedType; + +export const useDevServerEvents = (onMessage: (event: MessageEvent) => void, subscribe = true) => { + const prevOnMessage = useRef(onMessage); + + useEffect(() => { + if (prevOnMessage.current) { + DevServerObserver.unsubscribe(prevOnMessage.current); + } + if (!subscribe) { + return; + } + + DevServerObserver.subscribe(onMessage); + prevOnMessage.current = onMessage; + + return () => { + DevServerObserver.unsubscribe(onMessage); + DevServerObserver.close(); + }; + }, [onMessage, subscribe]); +}; + +export const Layout = () => { + const [events, setEvents] = useState([]); + useDevServerEvents((m) => { + console.log('event', m); + setEvents((v) => [...v, {data: m.data, time: new Date()}]); + }); + + return ( + <> + {events.map((e) => ( +

+ {e.data} {e.time.getTime()} +

+ ))} + + ); +}; diff --git a/packages/yii-dev-panel/src/Module/DevServer/Pages/index.ts b/packages/yii-dev-panel/src/Module/DevServer/Pages/index.ts new file mode 100644 index 0000000..df601b9 --- /dev/null +++ b/packages/yii-dev-panel/src/Module/DevServer/Pages/index.ts @@ -0,0 +1 @@ +export {Layout} from '@yiisoft/yii-dev-panel/Module/DevServer/Pages/Layout'; diff --git a/packages/yii-dev-panel/src/Module/DevServer/api.ts b/packages/yii-dev-panel/src/Module/DevServer/api.ts new file mode 100644 index 0000000..800dea9 --- /dev/null +++ b/packages/yii-dev-panel/src/Module/DevServer/api.ts @@ -0,0 +1,15 @@ +import {framesSlice} from '@yiisoft/yii-dev-panel/Module/DevServer/Context/Context'; +import {persistReducer} from 'redux-persist'; +import storage from 'redux-persist/lib/storage'; + +const framesSliceConfig = { + key: framesSlice.name, + version: 1, + storage, +}; + +export const reducers = { + [framesSlice.name]: persistReducer(framesSliceConfig, framesSlice.reducer), +}; + +export const middlewares = []; diff --git a/packages/yii-dev-panel/src/Module/DevServer/index.ts b/packages/yii-dev-panel/src/Module/DevServer/index.ts new file mode 100644 index 0000000..f6dbff7 --- /dev/null +++ b/packages/yii-dev-panel/src/Module/DevServer/index.ts @@ -0,0 +1,10 @@ +import {ModuleInterface} from '@yiisoft/yii-dev-panel-sdk/Types/Module.types'; +import {middlewares, reducers} from '@yiisoft/yii-dev-panel/Module/DevServer/api'; +import {routes} from '@yiisoft/yii-dev-panel/Module/DevServer/router'; + +export const DevServerModule: ModuleInterface = { + routes: routes, + reducers: reducers, + middlewares: middlewares, + standaloneModule: false, +}; diff --git a/packages/yii-dev-panel/src/Module/DevServer/router.tsx b/packages/yii-dev-panel/src/Module/DevServer/router.tsx new file mode 100644 index 0000000..28ce940 --- /dev/null +++ b/packages/yii-dev-panel/src/Module/DevServer/router.tsx @@ -0,0 +1,9 @@ +import * as Pages from '@yiisoft/yii-dev-panel/Module/DevServer/Pages'; +import {RouteObject} from 'react-router-dom'; + +export const routes = [ + { + path: '/dev-server', + element: , + }, +] satisfies RouteObject[]; diff --git a/packages/yii-dev-panel/src/modules.ts b/packages/yii-dev-panel/src/modules.ts index 3921492..de73424 100644 --- a/packages/yii-dev-panel/src/modules.ts +++ b/packages/yii-dev-panel/src/modules.ts @@ -1,8 +1,17 @@ import {ApplicationModule} from '@yiisoft/yii-dev-panel/Application'; import {DebugModule} from '@yiisoft/yii-dev-panel/Module/Debug'; +import {DevServerModule} from '@yiisoft/yii-dev-panel/Module/DevServer'; import {FramesModule} from '@yiisoft/yii-dev-panel/Module/Frames'; import {GiiModule} from '@yiisoft/yii-dev-panel/Module/Gii'; import {InspectorModule} from '@yiisoft/yii-dev-panel/Module/Inspector'; import {OpenApiModule} from '@yiisoft/yii-dev-panel/Module/OpenApi'; -export const modules = [ApplicationModule, DebugModule, GiiModule, InspectorModule, OpenApiModule, FramesModule]; +export const modules = [ + ApplicationModule, + DebugModule, + GiiModule, + InspectorModule, + OpenApiModule, + FramesModule, + DevServerModule, +]; From 62984acd6801a9830eaf4deaa69c5d1822ec1c6a Mon Sep 17 00:00:00 2001 From: Dmitrii Derepko Date: Mon, 11 Sep 2023 03:34:34 +0700 Subject: [PATCH 3/7] Improve dev-server view --- .../src/Component/ServerSentEventsObserver.ts | 9 +++ .../src/Helper/formatDate.ts | 5 +- .../src/Module/DevServer/Pages/Layout.tsx | 66 ++++++++++++++++--- 3 files changed, 67 insertions(+), 13 deletions(-) diff --git a/packages/yii-dev-panel-sdk/src/Component/ServerSentEventsObserver.ts b/packages/yii-dev-panel-sdk/src/Component/ServerSentEventsObserver.ts index e85a107..793354e 100644 --- a/packages/yii-dev-panel-sdk/src/Component/ServerSentEventsObserver.ts +++ b/packages/yii-dev-panel-sdk/src/Component/ServerSentEventsObserver.ts @@ -9,6 +9,15 @@ export class ServerSentEvents { subscribe(subscriber: (event: MessageEvent) => void) { if (this.eventSource === null || this.eventSource.readyState === EventSource.CLOSED) { this.eventSource = new EventSource(this.url); + this.eventSource.onopen = () => { + console.log('ServerSentEvents: connected'); + }; + this.eventSource.onerror = () => { + console.log('ServerSentEvents: error', this.listeners); + this.listeners.forEach((listener) => { + this.eventSource.addEventListener('message', listener); + }); + }; } this.listeners.push(subscriber); this.eventSource.addEventListener('message', subscriber); diff --git a/packages/yii-dev-panel-sdk/src/Helper/formatDate.ts b/packages/yii-dev-panel-sdk/src/Helper/formatDate.ts index 86b0a94..afd1982 100644 --- a/packages/yii-dev-panel-sdk/src/Helper/formatDate.ts +++ b/packages/yii-dev-panel-sdk/src/Helper/formatDate.ts @@ -1,8 +1,7 @@ -import {fromUnixTime} from 'date-fns'; import format from 'date-fns/format'; export function formatDate(unixTimeStamp: number) { - return format(fromUnixTime(unixTimeStamp), 'do MMM HH:mm:ss'); + return format(unixTimeStamp, 'do MMM HH:mm:ss'); } export function formatMicrotime(unixTimeStamp: number) { @@ -11,7 +10,7 @@ export function formatMicrotime(unixTimeStamp: number) { export function formatWithMicrotime(unixTimeStamp: number, dateFormat: string) { console.log(unixTimeStamp); const float = String(unixTimeStamp).split('.'); - return format(fromUnixTime(unixTimeStamp), dateFormat) + (float.length === 2 ? '.' + float[1].padEnd(6, '0') : ''); + return format(unixTimeStamp, dateFormat) + (float.length === 2 ? '.' + float[1].padEnd(6, '0') : ''); } export function formatMillisecondsAsDuration(milliseconds: number) { diff --git a/packages/yii-dev-panel/src/Module/DevServer/Pages/Layout.tsx b/packages/yii-dev-panel/src/Module/DevServer/Pages/Layout.tsx index 78fa815..0849d9b 100644 --- a/packages/yii-dev-panel/src/Module/DevServer/Pages/Layout.tsx +++ b/packages/yii-dev-panel/src/Module/DevServer/Pages/Layout.tsx @@ -1,6 +1,12 @@ +import DataObjectIcon from '@mui/icons-material/DataObject'; +import TableRowsIcon from '@mui/icons-material/TableRows'; +import {Button, List, ListItem, ListItemIcon, ListItemSecondaryAction, ListItemText, Tooltip} from '@mui/material'; +import Avatar from '@mui/material/Avatar'; +import Typography from '@mui/material/Typography'; import {ServerSentEvents} from '@yiisoft/yii-dev-panel-sdk/Component/ServerSentEventsObserver'; import {Config} from '@yiisoft/yii-dev-panel-sdk/Config'; -import {useEffect, useRef, useState} from 'react'; +import {formatDate} from '@yiisoft/yii-dev-panel-sdk/Helper/formatDate'; +import {useCallback, useEffect, useRef, useState} from 'react'; const DevServerObserver = new ServerSentEvents(Config.backendUrl + '/debug/api/dev'); @@ -30,6 +36,7 @@ export const useDevServerEvents = (onMessage: (event: MessageEvent) prevOnMessage.current = onMessage; return () => { + console.log('destroy'); DevServerObserver.unsubscribe(onMessage); DevServerObserver.close(); }; @@ -38,18 +45,57 @@ export const useDevServerEvents = (onMessage: (event: MessageEvent) export const Layout = () => { const [events, setEvents] = useState([]); - useDevServerEvents((m) => { - console.log('event', m); - setEvents((v) => [...v, {data: m.data, time: new Date()}]); - }); + useDevServerEvents( + useCallback((m) => { + // console.log('event', m); + setEvents((v) => [...v, {data: m.data, time: new Date()}]); + }, []), + ); return ( <> - {events.map((e) => ( -

- {e.data} {e.time.getTime()} -

- ))} + Total events: {events.length} + + + {events.map((e) => { + const data = JSON.parse(e.data); + if (data[0] === 43) { + return ( + + + + + + + {data[1]} + {formatDate(e.time.getTime())} + + ); + } + if (data[0] === 27) { + return ( + + + + + + + {data[1]} + {formatDate(e.time.getTime())} + + ); + } + return ( + + + + + {data[1]} + {formatDate(e.time.getTime())} + + ); + })} + ); }; From f7f03e6de5d3804f5fcd149aa1e7e92d46b1d6a1 Mon Sep 17 00:00:00 2001 From: Dmitrii Derepko Date: Sat, 16 Sep 2023 13:28:57 +0300 Subject: [PATCH 4/7] Add debug server menu --- .../yii-dev-panel/src/Application/Component/Layout.tsx | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/packages/yii-dev-panel/src/Application/Component/Layout.tsx b/packages/yii-dev-panel/src/Application/Component/Layout.tsx index 20dabdb..6d609c7 100644 --- a/packages/yii-dev-panel/src/Application/Component/Layout.tsx +++ b/packages/yii-dev-panel/src/Application/Component/Layout.tsx @@ -1,5 +1,6 @@ import {ContentCut, GitHub, Refresh} from '@mui/icons-material'; import AdbIcon from '@mui/icons-material/Adb'; +import InfoIcon from '@mui/icons-material/Info'; import { CssBaseline, IconButton, @@ -180,10 +181,13 @@ export const Layout = React.memo(({children}: React.PropsWithChildren) => { })}
- + - + + + + From de6812deba2e141e3546fd9e9dd89483ec9522fb Mon Sep 17 00:00:00 2001 From: Dmitrii Derepko Date: Sat, 16 Sep 2023 13:37:10 +0300 Subject: [PATCH 5/7] Add some features to the debug server --- .../src/Module/DevServer/Pages/Layout.tsx | 159 ++++++++++++------ 1 file changed, 111 insertions(+), 48 deletions(-) diff --git a/packages/yii-dev-panel/src/Module/DevServer/Pages/Layout.tsx b/packages/yii-dev-panel/src/Module/DevServer/Pages/Layout.tsx index 0849d9b..b3ab1c9 100644 --- a/packages/yii-dev-panel/src/Module/DevServer/Pages/Layout.tsx +++ b/packages/yii-dev-panel/src/Module/DevServer/Pages/Layout.tsx @@ -1,27 +1,29 @@ import DataObjectIcon from '@mui/icons-material/DataObject'; import TableRowsIcon from '@mui/icons-material/TableRows'; -import {Button, List, ListItem, ListItemIcon, ListItemSecondaryAction, ListItemText, Tooltip} from '@mui/material'; +import { + Badge, + Button, + List, + ListItem, + ListItemIcon, + ListItemText, + Stack, + ToggleButton, + ToggleButtonGroup, + ToggleButtonProps, + Tooltip, +} from '@mui/material'; + import Avatar from '@mui/material/Avatar'; -import Typography from '@mui/material/Typography'; +import {JsonRenderer} from '@yiisoft/yii-dev-panel-sdk/Component/JsonRenderer'; import {ServerSentEvents} from '@yiisoft/yii-dev-panel-sdk/Component/ServerSentEventsObserver'; import {Config} from '@yiisoft/yii-dev-panel-sdk/Config'; import {formatDate} from '@yiisoft/yii-dev-panel-sdk/Helper/formatDate'; -import {useCallback, useEffect, useRef, useState} from 'react'; +import {forwardRef, MouseEvent, useCallback, useEffect, useRef, useState} from 'react'; const DevServerObserver = new ServerSentEvents(Config.backendUrl + '/debug/api/dev'); -type DebugUpdatedType = { - type: EventTypesEnum.DebugUpdated; - payload: {}; -}; - -export enum EventTypesEnum { - DebugUpdated = 'debug-updated', -} - -export type EventTypes = DebugUpdatedType; - -export const useDevServerEvents = (onMessage: (event: MessageEvent) => void, subscribe = true) => { +export const useDevServerEvents = (onMessage: (event: MessageEvent) => void, subscribe = true) => { const prevOnMessage = useRef(onMessage); useEffect(() => { @@ -43,55 +45,116 @@ export const useDevServerEvents = (onMessage: (event: MessageEvent) }, [onMessage, subscribe]); }; +export const BadgedToggleButton = forwardRef( + (props, ref) => { + const {badgeContent, children, ...others} = props; + + return ( + + + {children} + + + ); + }, +); + +enum EventTypeEnum { + VAR_DUMPER = 27, + LOGS = 43, +} + +type EventType = { + data: string; + time: Date; + type: EventTypeEnum; +}; + +function DebugEntryIcon({type}: {type: EventTypeEnum | undefined}) { + if (type === EventTypeEnum.VAR_DUMPER) { + return ( + + + + ); + } + if (type === EventTypeEnum.LOGS) { + return ( + + + + ); + } + + return ; +} + export const Layout = () => { - const [events, setEvents] = useState([]); + const [events, setEvents] = useState([]); + const [eventsCounter, setEventsCounter] = useState>({ + [EventTypeEnum.VAR_DUMPER]: 0, + [EventTypeEnum.LOGS]: 0, + }); useDevServerEvents( useCallback((m) => { // console.log('event', m); - setEvents((v) => [...v, {data: m.data, time: new Date()}]); + const data = JSON.parse(m.data); + setEventsCounter((v) => ({...v, [data[0]]: v[data[0]] + 1})); + setEvents((v) => [...v, {data: data[1], time: new Date(), type: data[0] as EventTypeEnum}]); }, []), ); + const [types, setTypes] = useState([EventTypeEnum.VAR_DUMPER, EventTypeEnum.LOGS]); + + const handleFormat = (event: MouseEvent, types: EventTypeEnum[]) => { + setTypes(types); + }; + + const handleClear = (event: MouseEvent) => { + setEvents([]); + setEventsCounter({ + [EventTypeEnum.VAR_DUMPER]: 0, + [EventTypeEnum.LOGS]: 0, + }); + }; return ( <> - Total events: {events.length} - +

Debug Server Listener

+ + + + + + + +  Logs + + + +  VarDumper + + + {events.map((e) => { - const data = JSON.parse(e.data); - if (data[0] === 43) { - return ( - - - - - - - {data[1]} - {formatDate(e.time.getTime())} - - ); - } - if (data[0] === 27) { - return ( - - - - - - - {data[1]} - {formatDate(e.time.getTime())} - - ); + if (!types.includes(e.type)) { + return null; } return ( - + - {data[1]} - {formatDate(e.time.getTime())} + + {e.type === EventTypeEnum.VAR_DUMPER ? ( + + ) : ( + e.data + )} + ); })} From d332260b2575072f8218e2c299ab14bafcb8a5db Mon Sep 17 00:00:00 2001 From: Dmitrii Derepko Date: Sat, 16 Sep 2023 13:52:59 +0300 Subject: [PATCH 6/7] Decompose log entry rendering --- .../src/Component/LogEntry.tsx | 34 +++++++++++++++++++ .../src/Helper/collorMapper.ts | 19 +++++++++++ .../yii-dev-panel-sdk/src/Types/logger.ts | 1 + .../Module/Debug/Component/Panel/LogPanel.tsx | 27 ++------------- .../src/Module/DevServer/Pages/Layout.tsx | 17 +++++++--- .../src/Module/DevServer/router.tsx | 2 +- 6 files changed, 69 insertions(+), 31 deletions(-) create mode 100644 packages/yii-dev-panel-sdk/src/Component/LogEntry.tsx create mode 100644 packages/yii-dev-panel-sdk/src/Helper/collorMapper.ts create mode 100644 packages/yii-dev-panel-sdk/src/Types/logger.ts diff --git a/packages/yii-dev-panel-sdk/src/Component/LogEntry.tsx b/packages/yii-dev-panel-sdk/src/Component/LogEntry.tsx new file mode 100644 index 0000000..b39b309 --- /dev/null +++ b/packages/yii-dev-panel-sdk/src/Component/LogEntry.tsx @@ -0,0 +1,34 @@ +import {FilePresent} from '@mui/icons-material'; +import {Alert, AlertTitle, Link} from '@mui/material'; +import Box from '@mui/material/Box'; +import {JsonRenderer} from '@yiisoft/yii-dev-panel-sdk/Component/JsonRenderer'; +import {phpLoggerLevelToAlertColor} from '@yiisoft/yii-dev-panel-sdk/Helper/collorMapper'; +import {parseFilePathWithLineAnchor} from '@yiisoft/yii-dev-panel-sdk/Helper/filePathParser'; +import {PhpLoggerLevel} from '@yiisoft/yii-dev-panel-sdk/Types/logger'; + +export type LogEntry = { + context: object; + level: PhpLoggerLevel; + line?: string; + message: string; + time: number; +}; +type LogEntryProps = { + entry: LogEntry; +}; +export const LogEntry = ({entry}: LogEntryProps) => { + return ( + + {entry.message} + + + {'line' in entry && ( + + {entry.line} + + + )} + + + ); +}; diff --git a/packages/yii-dev-panel-sdk/src/Helper/collorMapper.ts b/packages/yii-dev-panel-sdk/src/Helper/collorMapper.ts new file mode 100644 index 0000000..c63133b --- /dev/null +++ b/packages/yii-dev-panel-sdk/src/Helper/collorMapper.ts @@ -0,0 +1,19 @@ +import {AlertColor} from '@mui/material'; +import {PhpLoggerLevel} from '@yiisoft/yii-dev-panel-sdk/Types/logger'; + +export const phpLoggerLevelToAlertColor = (status: PhpLoggerLevel): AlertColor => { + switch (status) { + case 'emergency': + case 'alert': + case 'critical': + case 'error': + return 'error'; + case 'warning': + return 'warning'; + case 'notice': + case 'info': + case 'debug': + return 'info'; + } + return 'success'; +}; diff --git a/packages/yii-dev-panel-sdk/src/Types/logger.ts b/packages/yii-dev-panel-sdk/src/Types/logger.ts new file mode 100644 index 0000000..b45cb14 --- /dev/null +++ b/packages/yii-dev-panel-sdk/src/Types/logger.ts @@ -0,0 +1 @@ +export type PhpLoggerLevel = 'emergency' | 'alert' | 'critical' | 'error' | 'warning' | 'notice' | 'info' | 'debug'; diff --git a/packages/yii-dev-panel/src/Module/Debug/Component/Panel/LogPanel.tsx b/packages/yii-dev-panel/src/Module/Debug/Component/Panel/LogPanel.tsx index 36598f1..0890ae0 100644 --- a/packages/yii-dev-panel/src/Module/Debug/Component/Panel/LogPanel.tsx +++ b/packages/yii-dev-panel/src/Module/Debug/Component/Panel/LogPanel.tsx @@ -1,17 +1,5 @@ -import {FilePresent} from '@mui/icons-material'; -import {Alert, AlertTitle, Link} from '@mui/material'; -import Box from '@mui/material/Box'; -import {parseFilePathWithLineAnchor} from '@yiisoft/yii-dev-panel-sdk/Helper/filePathParser'; -import {JsonRenderer} from '@yiisoft/yii-dev-panel/Module/Debug/Component/JsonRenderer'; +import {LogEntry} from '@yiisoft/yii-dev-panel-sdk/Component/LogEntry'; -type Level = 'error' | 'info' | 'debug'; -type LogEntry = { - context: object; - level: Level; - line: string; - message: string; - time: number; -}; type LogPanelProps = { data: LogEntry[]; }; @@ -22,18 +10,7 @@ export const LogPanel = ({data}: LogPanelProps) => { {!data || data.length === 0 ? ( <>Nothing here ) : ( - data.map((entry, index) => ( - - {entry.message} - - - - {entry.line} - - - - - )) + data.map((entry, index) => ) )} ); diff --git a/packages/yii-dev-panel/src/Module/DevServer/Pages/Layout.tsx b/packages/yii-dev-panel/src/Module/DevServer/Pages/Layout.tsx index b3ab1c9..356fae0 100644 --- a/packages/yii-dev-panel/src/Module/DevServer/Pages/Layout.tsx +++ b/packages/yii-dev-panel/src/Module/DevServer/Pages/Layout.tsx @@ -16,6 +16,7 @@ import { import Avatar from '@mui/material/Avatar'; import {JsonRenderer} from '@yiisoft/yii-dev-panel-sdk/Component/JsonRenderer'; +import {LogEntry} from '@yiisoft/yii-dev-panel-sdk/Component/LogEntry'; import {ServerSentEvents} from '@yiisoft/yii-dev-panel-sdk/Component/ServerSentEventsObserver'; import {Config} from '@yiisoft/yii-dev-panel-sdk/Config'; import {formatDate} from '@yiisoft/yii-dev-panel-sdk/Helper/formatDate'; @@ -89,6 +90,16 @@ function DebugEntryIcon({type}: {type: EventTypeEnum | undefined}) { return ; } +function DebugEntryContent({data, type}: {data: string; type: EventTypeEnum}) { + if (type === EventTypeEnum.VAR_DUMPER) { + return ; + } + if (type === EventTypeEnum.LOGS) { + return ; + } + return <>{data}; +} + export const Layout = () => { const [events, setEvents] = useState([]); const [eventsCounter, setEventsCounter] = useState>({ @@ -149,11 +160,7 @@ export const Layout = () => {
- {e.type === EventTypeEnum.VAR_DUMPER ? ( - - ) : ( - e.data - )} + ); diff --git a/packages/yii-dev-panel/src/Module/DevServer/router.tsx b/packages/yii-dev-panel/src/Module/DevServer/router.tsx index 28ce940..5a62e73 100644 --- a/packages/yii-dev-panel/src/Module/DevServer/router.tsx +++ b/packages/yii-dev-panel/src/Module/DevServer/router.tsx @@ -3,7 +3,7 @@ import {RouteObject} from 'react-router-dom'; export const routes = [ { - path: '/dev-server', + path: '/debug-server', element: , }, ] satisfies RouteObject[]; From bb39de828fe81a38f0fd6b3d26a6578a6864677b Mon Sep 17 00:00:00 2001 From: Dmitrii Derepko Date: Fri, 16 Aug 2024 09:57:41 +0300 Subject: [PATCH 7/7] Refactor observers --- .../src/Component/ServerSentEventsObserver.ts | 3 +- .../src/Component/useDevServerEvents.ts | 21 +++++--- .../src/Component/useServerSentEvents.ts | 2 +- .../src/Module/DevServer/Pages/Layout.tsx | 49 ++++++------------- packages/yii-dev-panel/src/vite-env.d.ts | 1 + 5 files changed, 31 insertions(+), 45 deletions(-) diff --git a/packages/yii-dev-panel-sdk/src/Component/ServerSentEventsObserver.ts b/packages/yii-dev-panel-sdk/src/Component/ServerSentEventsObserver.ts index 5601c9b..4b129ba 100644 --- a/packages/yii-dev-panel-sdk/src/Component/ServerSentEventsObserver.ts +++ b/packages/yii-dev-panel-sdk/src/Component/ServerSentEventsObserver.ts @@ -41,5 +41,4 @@ export class ServerSentEvents { } } -export const createServerSentEventsObserver = (backendUrl: string) => - new ServerSentEvents(backendUrl + '/debug/api/event-stream'); +export const createServerSentEventsObserver = (url: string) => new ServerSentEvents(url); diff --git a/packages/yii-dev-panel-sdk/src/Component/useDevServerEvents.ts b/packages/yii-dev-panel-sdk/src/Component/useDevServerEvents.ts index eb1dfbe..0a91d72 100644 --- a/packages/yii-dev-panel-sdk/src/Component/useDevServerEvents.ts +++ b/packages/yii-dev-panel-sdk/src/Component/useDevServerEvents.ts @@ -1,4 +1,4 @@ -import {ServerSentEventsObserver} from '@yiisoft/yii-dev-panel-sdk/Component/ServerSentEventsObserver'; +import {createServerSentEventsObserver} from '@yiisoft/yii-dev-panel-sdk/Component/ServerSentEventsObserver'; import {useEffect, useRef} from 'react'; type DebugUpdatedType = { @@ -12,23 +12,30 @@ export enum EventTypesEnum { export type EventTypes = DebugUpdatedType; -export const useDevServerEvents = (onMessage: (event: MessageEvent) => void, subscribe = true) => { +export const useServerSentEvents = ( + backendUrl: string, + onMessage: (event: MessageEvent) => void, + subscribe = true, +) => { const prevOnMessage = useRef(onMessage); + const ServerSentEventsObserverRef = useRef(createServerSentEventsObserver(backendUrl + '/debug/api/dev')); useEffect(() => { if (prevOnMessage.current) { - ServerSentEventsObserver.unsubscribe(prevOnMessage.current); + ServerSentEventsObserverRef.current.unsubscribe(prevOnMessage.current); } if (!subscribe) { - return; + return () => { + ServerSentEventsObserverRef.current.unsubscribe(onMessage); + }; } - ServerSentEventsObserver.subscribe(onMessage); + ServerSentEventsObserverRef.current.subscribe(onMessage); prevOnMessage.current = onMessage; return () => { - ServerSentEventsObserver.unsubscribe(onMessage); - ServerSentEventsObserver.close(); + ServerSentEventsObserverRef.current.unsubscribe(onMessage); + ServerSentEventsObserverRef.current.close(); }; }, [onMessage, subscribe]); }; diff --git a/packages/yii-dev-panel-sdk/src/Component/useServerSentEvents.ts b/packages/yii-dev-panel-sdk/src/Component/useServerSentEvents.ts index 4421ff3..a02b121 100644 --- a/packages/yii-dev-panel-sdk/src/Component/useServerSentEvents.ts +++ b/packages/yii-dev-panel-sdk/src/Component/useServerSentEvents.ts @@ -18,7 +18,7 @@ export const useServerSentEvents = ( subscribe = true, ) => { const prevOnMessage = useRef(onMessage); - const ServerSentEventsObserverRef = useRef(createServerSentEventsObserver(backendUrl)); + const ServerSentEventsObserverRef = useRef(createServerSentEventsObserver(backendUrl + '/debug/api/event-stream')); useEffect(() => { if (prevOnMessage.current) { diff --git a/packages/yii-dev-panel/src/Module/DevServer/Pages/Layout.tsx b/packages/yii-dev-panel/src/Module/DevServer/Pages/Layout.tsx index 356fae0..8ffdc32 100644 --- a/packages/yii-dev-panel/src/Module/DevServer/Pages/Layout.tsx +++ b/packages/yii-dev-panel/src/Module/DevServer/Pages/Layout.tsx @@ -17,34 +17,10 @@ import { import Avatar from '@mui/material/Avatar'; import {JsonRenderer} from '@yiisoft/yii-dev-panel-sdk/Component/JsonRenderer'; import {LogEntry} from '@yiisoft/yii-dev-panel-sdk/Component/LogEntry'; -import {ServerSentEvents} from '@yiisoft/yii-dev-panel-sdk/Component/ServerSentEventsObserver'; -import {Config} from '@yiisoft/yii-dev-panel-sdk/Config'; import {formatDate} from '@yiisoft/yii-dev-panel-sdk/Helper/formatDate'; -import {forwardRef, MouseEvent, useCallback, useEffect, useRef, useState} from 'react'; - -const DevServerObserver = new ServerSentEvents(Config.backendUrl + '/debug/api/dev'); - -export const useDevServerEvents = (onMessage: (event: MessageEvent) => void, subscribe = true) => { - const prevOnMessage = useRef(onMessage); - - useEffect(() => { - if (prevOnMessage.current) { - DevServerObserver.unsubscribe(prevOnMessage.current); - } - if (!subscribe) { - return; - } - - DevServerObserver.subscribe(onMessage); - prevOnMessage.current = onMessage; - - return () => { - console.log('destroy'); - DevServerObserver.unsubscribe(onMessage); - DevServerObserver.close(); - }; - }, [onMessage, subscribe]); -}; +import {forwardRef, MouseEvent, useCallback, useState} from 'react'; +import {useSelector} from '@yiisoft/yii-dev-panel/store'; +import {useServerSentEvents} from '@yiisoft/yii-dev-panel-sdk/Component/useDevServerEvents'; export const BadgedToggleButton = forwardRef( (props, ref) => { @@ -106,14 +82,17 @@ export const Layout = () => { [EventTypeEnum.VAR_DUMPER]: 0, [EventTypeEnum.LOGS]: 0, }); - useDevServerEvents( - useCallback((m) => { - // console.log('event', m); - const data = JSON.parse(m.data); - setEventsCounter((v) => ({...v, [data[0]]: v[data[0]] + 1})); - setEvents((v) => [...v, {data: data[1], time: new Date(), type: data[0] as EventTypeEnum}]); - }, []), - ); + const backendUrl = useSelector((state) => state.application.baseUrl) as string; + + const onUpdatesHandler = useCallback((m) => { + console.log('event', m); + const data = JSON.parse(m.data); + setEventsCounter((v) => ({...v, [data[0]]: v[data[0]] + 1})); + setEvents((v) => [...v, {data: data[1], time: new Date(), type: data[0] as EventTypeEnum}]); + }, []); + + useServerSentEvents(backendUrl, onUpdatesHandler, true); + const [types, setTypes] = useState([EventTypeEnum.VAR_DUMPER, EventTypeEnum.LOGS]); const handleFormat = (event: MouseEvent, types: EventTypeEnum[]) => { diff --git a/packages/yii-dev-panel/src/vite-env.d.ts b/packages/yii-dev-panel/src/vite-env.d.ts index f01a558..8dc3a67 100644 --- a/packages/yii-dev-panel/src/vite-env.d.ts +++ b/packages/yii-dev-panel/src/vite-env.d.ts @@ -1,3 +1,4 @@ /// /// /// +///