refactor(Settings): a single settings pane#97
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
There was a problem hiding this comment.
Pull request overview
This PR refactors the settings UI to provide a more streamlined experience by consolidating three separate settings forms into a single sheet with an accordion interface. The changes improve code organization, add helpful tooltips throughout the app, and enhance form validation with better user feedback.
Key Changes
- Consolidated three separate settings sheets into one unified
Settingscomponent with an accordion interface for better navigation - Added a global
TooltipProviderwrapper and enriched the dock panel with keyboard shortcut tooltips for improved discoverability - Enhanced form validation and user feedback with success toast notifications and improved state management
Reviewed changes
Copilot reviewed 16 out of 16 changed files in this pull request and generated 13 comments.
Show a summary per file
| File | Description |
|---|---|
apps/electron-app/src/render/components/Settings.tsx |
New consolidated settings component using accordion pattern to group all settings forms |
apps/electron-app/src/render/components/forms/UserSettingsForm.tsx |
Removed Sheet wrapper, added toast notifications, improved form state management |
apps/electron-app/src/render/components/forms/MqttSettingsForm.tsx |
Removed Sheet wrapper, updated validation schema, added toast feedback |
apps/electron-app/src/render/components/forms/AdvancedSettingsForm.tsx |
Removed Sheet wrapper, reorganized UI with alerts, added toast notifications |
apps/electron-app/src/app.tsx |
Added global TooltipProvider wrapper and integrated new Settings component |
apps/electron-app/src/render/components/react-flow/panels/DockPanel.tsx |
Added tooltips with keyboard shortcuts to dock buttons, reordered settings menu |
apps/electron-app/src/render/components/react-flow/nodes/Node.tsx |
Removed redundant TooltipProvider wrapper |
apps/electron-app/src/render/components/react-flow/nodes/Figma.tsx |
Removed redundant TooltipProvider wrapper |
apps/electron-app/src/render/components/react-flow/Handle.tsx |
Removed redundant TooltipProvider wrapper |
apps/electron-app/src/main/menu.ts |
Renamed "Insert node" to "Add node" and reordered settings menu items |
packages/ui/components/ui/dock.tsx |
Added hover background styling to dock icons |
apps/electron-app/src/render/stores/yjs.ts |
Removed commented-out signaling server URLs |
apps/electron-app/package.json, apps/nextjs-app/package.json, apps/figma-plugin/package.json |
Version bumped to 0.8.5 |
apps/nextjs-app/components/DownloadApp.tsx |
Updated download version reference to 0.8.5 |
Comments suppressed due to low confidence (2)
apps/electron-app/src/render/components/forms/MqttSettingsForm.tsx:34
- Unused variable setSettingsOpen.
const { user, mqttConfig, setMqttConfig, setSettingsOpen } = useAppStore();
apps/electron-app/src/render/components/react-flow/nodes/Figma.tsx:280
- Unused variable DEFAULT_FIGMA_VALUE_PER_TYPE.
const DEFAULT_FIGMA_VALUE_PER_TYPE: Record<FigmaVariable['resolvedType'], FigmaValueType> = {
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| className={cn( | ||
| 'flex aspect-square cursor-pointer items-center justify-center rounded-full', | ||
| 'flex aspect-square cursor-pointer items-center justify-center rounded-full hover:bg-muted-foreground', | ||
| disableMagnification && 'hover:bg-muted-foreground transition-colors', |
There was a problem hiding this comment.
The hover:bg-muted-foreground class is now applied unconditionally (line 131), but it's also conditionally applied on line 132 when disableMagnification is true. This creates redundant styling. The second condition should be removed or the logic should be restructured to avoid duplication.
| disableMagnification && 'hover:bg-muted-foreground transition-colors', | |
| disableMagnification && 'transition-colors', |
| export function MqttSettingsForm(props: Props) { | ||
| const { user, mqttConfig, setMqttConfig } = useAppStore(); | ||
| export function MqttSettingsForm() { | ||
| const { user, mqttConfig, setMqttConfig, setSettingsOpen } = useAppStore(); |
There was a problem hiding this comment.
The setSettingsOpen variable is destructured from useAppStore() but is never used in this component. It should be removed from the destructuring assignment.
| const { user, mqttConfig, setMqttConfig, setSettingsOpen } = useAppStore(); | |
| const { user, mqttConfig, setMqttConfig } = useAppStore(); |
| <a | ||
| className='underline' | ||
| href='https://www.figma.com/community/plugin/1373258770799080545/figma-hardware-bridge' | ||
| target='_blank' |
There was a problem hiding this comment.
The anchor tag with target='_blank' should include rel='noopener noreferrer' for security. Without this, the opened page can access the window.opener property and potentially redirect the parent page, creating a security vulnerability.
| target='_blank' | |
| target='_blank' | |
| rel='noopener noreferrer' |
| )} | ||
| /> | ||
| <div className='flex justify-end gap-2 pt-2'> | ||
| <Button type='submit' disabled={!form.formState.dirtyFields || !form.formState.isValid}> |
There was a problem hiding this comment.
The condition !form.formState.dirtyFields is incorrect. dirtyFields is an object, not a boolean. Use !form.formState.isDirty instead to properly check if the form has been modified.
| <Button type='submit' disabled={!form.formState.dirtyFields || !form.formState.isValid}> | |
| <Button type='submit' disabled={!form.formState.isDirty || !form.formState.isValid}> |
| const schema = Zod.object({ | ||
| host: Zod.string().optional(), | ||
| port: Zod.number().optional(), | ||
| host: Zod.url().or(Zod.ipv4()), |
There was a problem hiding this comment.
The host validation Zod.url().or(Zod.ipv4()) is too restrictive. Plain hostnames like 'test.mosquitto.org' or 'localhost' are valid MQTT hosts but are not URLs (missing protocol). Consider using Zod.string().min(1) with a custom validation that accepts hostnames, URLs, and IP addresses, or use a regex pattern that matches valid hostnames.
| Microcontroller settings | ||
| </div> | ||
| </AccordionTrigger> | ||
| <AccordionContent> |
There was a problem hiding this comment.
The AccordionContent components have inconsistent className props. The first two have className='px-1' (lines 65, 76) while the third one (line 87) is missing this prop. For consistency, either add className='px-1' to the third AccordionContent or remove it from all if not needed.
| <AccordionContent> | |
| <AccordionContent className='px-1'> |
| <Icons.ExternalLink size={16} /> | ||
| </AlertTitle> | ||
| <AlertDescription> | ||
| If you need to control a LED strip over WiFi, add the <code>node-pixel firmare</code> to{' '} |
There was a problem hiding this comment.
Spelling error: 'firmare' should be 'firmware'.
| If you need to control a LED strip over WiFi, add the <code>node-pixel firmare</code> to{' '} | |
| If you need to control a LED strip over WiFi, add the <code>node-pixel firmware</code> to{' '} |
| import { Toaster, TooltipProvider } from '@microflow/ui'; | ||
| import { ReactFlowProvider } from '@xyflow/react'; | ||
| import { createRoot } from 'react-dom/client'; | ||
| import { useDarkMode, useLocalStorage } from 'usehooks-ts'; |
There was a problem hiding this comment.
Unused import useLocalStorage.
| import { useDarkMode, useLocalStorage } from 'usehooks-ts'; | |
| import { useDarkMode } from 'usehooks-ts'; |
| toast, | ||
| } from '@microflow/ui'; | ||
| import { useLocalStorage } from 'usehooks-ts'; | ||
| import { useAppStore } from '../../stores/app'; |
There was a problem hiding this comment.
Unused import useAppStore.
| import { useAppStore } from '../../stores/app'; |
| } from '@microflow/ui'; | ||
| import { Icons, Switch, Tooltip, TooltipContent, TooltipTrigger } from '@microflow/ui'; | ||
| import { Position, useUpdateNodeInternals } from '@xyflow/react'; | ||
| import { useEffect, useMemo, useRef } from 'react'; |
There was a problem hiding this comment.
Unused import useMemo.
| import { useEffect, useMemo, useRef } from 'react'; | |
| import { useEffect, useRef } from 'react'; |
This pull request refactors the settings forms and UI in the Electron app to provide a more streamlined and user-friendly experience. The main changes include consolidating the separate settings forms into a single
Settingscomponent with an accordion interface, improving form validation and feedback, and updating the menu structure for better clarity. Additionally, several code cleanups and dependency updates are included.Settings UI Refactor:
Settingscomponent (Settings.tsx) that uses a sheet and accordion interface to groupUserSettingsForm,MqttSettingsForm, andAdvancedSettingsFormin one place, improving navigation and organization.app.tsxwith the new consolidatedSettingscomponent. [1] [2]Forms Improvements:
UserSettingsForm,MqttSettingsForm,AdvancedSettingsForm) to be standalone components, removed sheet wrappers, improved validation logic, and added toast notifications for successful saves. [1] [2] [3] [4] [5] [6]App Structure and UI Enhancements:
TooltipProviderfor consistent tooltip behavior throughout the application. [1] [2] [3]Menu Updates:
Version Update:
0.8.4to0.8.5inpackage.jsonto reflect these improvements.