chore: fixed admin design rework#7716
Conversation
ⓘ You've reached your Qodo monthly free-tier limit. Reviews pause until next month — upgrade your plan to continue now, or link your paid account if you already have one. |
Review Summary by QodoAdmin interface design rework with new color system and component library
WalkthroughsDescription• Complete admin UI redesign with modern forest-green color system • Rebuilt sidebar with collapsible navigation and improved visual hierarchy • Redesigned plugin manager with stats cards, better search/filtering • Overhauled pads management page with bulk actions and filtering • Restructured help page with version info, hooks browser, and diagnostics Diagramflowchart LR
A["Old Admin UI<br/>Basic styling"] -->|"Redesign"| B["New Design System<br/>Forest-green palette"]
B --> C["Sidebar<br/>Collapsible nav"]
B --> D["Plugin Manager<br/>Stats + tables"]
B --> E["Pads Manager<br/>Bulk actions"]
B --> F["Help Page<br/>Diagnostics"]
C --> G["Modern UX<br/>Improved usability"]
D --> G
E --> G
F --> G
File Changes1. admin/src/pages/Plugin.ts
|
Code Review by Qodo
1.
|
| useEffect(() => { | ||
| if(!settingsSocket){ | ||
| return | ||
| } | ||
| if (!settingsSocket) return | ||
|
|
||
| settingsSocket.on('results:padLoad', (data: PadSearchResult)=>{ | ||
| useStore.getState().setPads(data); | ||
| settingsSocket.on('results:padLoad', (data: PadSearchResult) => { | ||
| useStore.getState().setPads(data) | ||
| }) | ||
|
|
||
| settingsSocket.on('results:deletePad', (padID: string) => { | ||
| const newPads = useStore.getState().pads?.results?.filter(p => p.padName !== padID) | ||
| useStore.getState().setPads({total: useStore.getState().pads!.total - 1, results: newPads}) | ||
| }) | ||
|
|
||
| settingsSocket.on('results:deletePad', (padID: string)=>{ | ||
| const newPads = useStore.getState().pads?.results?.filter((pad)=>{ | ||
| return pad.padName !== padID | ||
| }) | ||
| useStore.getState().setPads({ | ||
| total: useStore.getState().pads!.total-1, | ||
| results: newPads | ||
| }) | ||
| type CreateResponse = {error: string} | {success: string} | ||
| settingsSocket.on('results:createPad', (rep: CreateResponse) => { | ||
| if ('error' in rep) { | ||
| useStore.getState().setToastState({open: true, title: rep.error, success: false}) | ||
| } else { | ||
| useStore.getState().setToastState({open: true, title: rep.success, success: true}) | ||
| setCreatePadDialogOpen(false) | ||
| settingsSocket.emit('padLoad', searchParams) | ||
| } | ||
| }) | ||
|
|
||
| type SettingsSocketCreateReponse = { | ||
| error: string | ||
| } | { | ||
| success: string | ||
| } | ||
| settingsSocket.on('results:cleanupPadRevisions', (data) => { | ||
| const newPads = useStore.getState().pads?.results ?? [] | ||
| if (data.error) { setErrorText(data.error); return } | ||
| newPads.forEach(p => { if (p.padName === data.padId) p.revisionNumber = data.keepRevisions }) | ||
| useStore.getState().setPads({results: newPads, total: useStore.getState().pads!.total}) | ||
| }) | ||
| }, [settingsSocket, pads]) |
There was a problem hiding this comment.
3. Pad listeners multiply 🐞 Bug ☼ Reliability
PadPage’s socket listener effect depends on pads and also updates pads inside listeners, so each update re-runs the effect and registers additional handlers, multiplying events over time.
Agent Prompt
### Issue description
`PadPage` registers multiple Socket.IO listeners in an effect that depends on `[settingsSocket, pads]`. Because the listeners update `pads`, the effect re-runs and re-registers listeners, causing handler duplication and progressively worse behavior.
### Issue Context
This will amplify actions like `padLoad` (multiple `setPads` calls), and also duplicates delete/create/cleanup handlers.
### Fix Focus Areas
- admin/src/pages/PadPage.tsx[105-134]
### Suggested fix
- Change the effect deps to `[settingsSocket]` (or `[settingsSocket, searchParams]` only if truly needed) and **remove `pads`**.
- Add cleanup that calls `settingsSocket.off(...)` for each registered event.
- Avoid mutating `useStore.getState().pads?.results` in place in `results:cleanupPadRevisions`; instead create a new array (e.g., `map`) and new objects before calling `setPads`.
ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools
No description provided.