bambuddy/frontend
maziggy 9033b0f81e feat(toast): restore upload-progress toast for scheduler dispatches (#1625 follow-up)
FTP push to the printer into the server-side scheduler tick. That
removed the browser-side upload the old XHR-progress modal listened
to — users only saw the queue item flip to "active" with no visibility
into the FTP push + the H2D/H2D Pro 80-210 s project_file digestion
window before the printer actually started.

Port the legacy bg-dispatch toast rendering from
0b43ac0d:frontend/src/contexts/ToastContext.tsx lines 510-650 back in
place verbatim — same DOM tree, same Tailwind classes, same
formatFileSize bytes line, same uppercase status chip, same collapse
chevron, same awaitingPrinter derivation, same auto-dismiss. The only
adapt is the event ingestion: a useEffect maps the four scheduler-side
WS events to the legacy DispatchToastJob shape.

The toast materializes when the FTP push to the printer ACTUALLY
STARTS (queue_item_uploading) — NOT on POST /queue. A draft that
fired at queue-add made the toast jump to "Dispatched" before any
upload had happened.

Four backend WS events drive it: uploading (carries printer_name +
total_bytes), upload_progress (throttled at 200 ms / 256 KB to match
legacy background_dispatch.py:614-615 1:1, first call always emits,
completion always emits; an _UploadProgressBridge bridges from the
FTP executor thread to the asyncio loop), acked (printer transitioned
out of pre_state), failed (with a reason key the toast looks up as
dispatchToast.failed.{reason}). No queue_item_dispatched event: the
legacy path kept status=processing from upload start until printer
ack, "Awaiting printer..." derives from upload_progress_pct >= 99.9
(legacy uploadDoneAwaitingPrinter trick).

Per-user routing: WS connect resolves the principal username to
User.id once and stashes it on websocket.state, so
ws_manager.broadcast_to_user filters O(connections). Auth-disabled
installs route user_id=None to all connections — matches the legacy
single-user behaviour. The watchdog receives created_by_id through a
new kwarg so the static method can still emit acked without
re-fetching the queue item.
2026-06-27 11:28:00 +02:00
..
docs [Fix] Virtual Printer FTP routed to wrong VP with different access codes (#735) 2026-03-18 09:04:31 +01:00
mockups - Refactored printer card's AMS section for better experience 2026-01-01 12:08:55 +01:00
public fix(a2l): transparent printer-card image + getPrinterImage resolver 2026-06-10 11:09:02 +02:00
scripts fix(printers): cam wall — offline tile chip + don't kill shared 2026-06-26 16:01:28 +02:00
src feat(toast): restore upload-progress toast for scheduler dispatches (#1625 follow-up) 2026-06-27 11:28:00 +02:00
.gitignore Added screenshots 2025-11-28 10:23:59 +01:00
.npmrc Fix npm audit high-severity minimatch ReDoS (GHSA-3ppc-4f35-3m26) 2026-02-19 08:23:53 +01:00
eslint.config.js Improved frontend tests 2026-01-30 13:02:57 +01:00
index.html fix: unbreak CSP for sidebar iframes, service worker, and Google Fonts 2026-04-13 16:38:17 +02:00
package-lock.json feat(file-manager): recursive subfolder search + per-folder markdown description panel (#1268) 2026-06-22 11:40:58 +02:00
package.json feat(file-manager): recursive subfolder search + per-folder markdown description panel (#1268) 2026-06-22 11:40:58 +02:00
postcss.config.js Added screenshots 2025-11-28 10:23:59 +01:00
README.md Added screenshots 2025-11-28 10:23:59 +01:00
tailwind.config.js Add SpoolBuddy tag detection modal and fix NFC reader silent failure 2026-02-28 08:54:39 +01:00
tsconfig.app.json Fix docker build 2025-12-12 16:48:12 +01:00
tsconfig.json Added screenshots 2025-11-28 10:23:59 +01:00
tsconfig.node.json Added screenshots 2025-11-28 10:23:59 +01:00
vite.config.ts fix(frontend): revert base: '' so deep SPA routes load their assets on initial navigation (issue #1221) 2026-05-08 08:39:00 +02:00
vitest.config.ts feat: Centralise sidebar ordering and add page visibility options (#1673) 2026-06-17 12:04:57 +02:00

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:

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...
    },
  },
])