a7b7327ce5
Adds an opt-in autosave feature (disabled by default) that silently
saves the canvas after a configurable period of inactivity.
- frontend/src/utils/autosaveSettings.ts (new) — localStorage-backed
setting {enabled, delay} with pub/sub CustomEvent pattern (mirrors
alignmentSettings.ts). Key: homelable.autosave.
- frontend/src/App.tsx:
* handleSave accepts optional { silent?: boolean } — skips the success
toast when called from autosave to avoid noise on every periodic save
* autosave state (useState + subscribeAutosaveSettings)
* debounce useEffect: resets on nodes/edges change; when quiet for
autosave.delay seconds and hasUnsavedChanges is true, calls
handleSaveRef.current silently
- frontend/src/components/modals/SettingsModal.tsx:
* Canvas section: Autosave canvas toggle + Save after delay selector
(3/5/10/30/60 s). Changes persist immediately to localStorage via
writeAutosaveSettings + propagate cross-tab via CustomEvent.
Default: disabled — no behaviour change for existing users.
Manual Ctrl+S and the Save button continue to work normally.
Errors always show a toast regardless of the silent flag.
React + TypeScript + Vite
This template provides a minimal setup to get React working in Vite with HMR and some ESLint rules.
Currently, two official plugins are available:
- @vitejs/plugin-react uses Babel (or oxc when used in rolldown-vite) for Fast Refresh
- @vitejs/plugin-react-swc uses SWC for Fast Refresh
React Compiler
The React Compiler is not enabled on this template because of its impact on dev & build performances. To add it, see this documentation.
Expanding the ESLint configuration
If you are developing a production application, we recommend updating the configuration to enable type-aware lint rules:
export default defineConfig([
globalIgnores(['dist']),
{
files: ['**/*.{ts,tsx}'],
extends: [
// Other configs...
// Remove tseslint.configs.recommended and replace with this
tseslint.configs.recommendedTypeChecked,
// Alternatively, use this for stricter rules
tseslint.configs.strictTypeChecked,
// Optionally, add this for stylistic rules
tseslint.configs.stylisticTypeChecked,
// Other configs...
],
languageOptions: {
parserOptions: {
project: ['./tsconfig.node.json', './tsconfig.app.json'],
tsconfigRootDir: import.meta.dirname,
},
// other options...
},
},
])
You can also install eslint-plugin-react-x and eslint-plugin-react-dom for React-specific lint rules:
// eslint.config.js
import reactX from 'eslint-plugin-react-x'
import reactDom from 'eslint-plugin-react-dom'
export default defineConfig([
globalIgnores(['dist']),
{
files: ['**/*.{ts,tsx}'],
extends: [
// Other configs...
// Enable lint rules for React
reactX.configs['recommended-typescript'],
// Enable lint rules for React DOM
reactDom.configs.recommended,
],
languageOptions: {
parserOptions: {
project: ['./tsconfig.node.json', './tsconfig.app.json'],
tsconfigRootDir: import.meta.dirname,
},
// other options...
},
},
])