- Introduced a new class to modify the default base CSS file by wrapping content after the 'body' selector in a CSS scope.
- Implemented methods to read the file, generate a patch, and apply the necessary modifications.
- Added error handling for cases where the 'body' block cannot be found.
- Created a new file for ToastPosition type definitions to improve code organization.
- Removed the inline ToastPosition type definition from mount-engine.ts and updated the import accordingly.
- Added a comment in app.config.ts for clarity on toaster settings.
- Added optional properties `expand`, `duration`, and `max` to the Notify interface.
- Updated NotificationSettings class to include validation for new properties.
- Modified the NotificationsService to parse and return the new settings.
- Adjusted the toaster configuration in the app to utilize the new settings.
- Updated GraphQL query to fetch the new notification settings.
Updates the notification sidebar to properly refresh notification counts (badges) when the API connection is restored or when the user manually retries.
Changes:
- Emit `refetched` event from `NotificationsList` when the query successfully returns data.
- Trigger `recalculateOverview` and `refetch` in `Sidebar` when the list is refreshed or when the API status becomes 'online'.
- Fixes an issue where notification badges would remain at 0 after an API outage, even though the notification list had populated correctly.
Problem:
ESLint was flagging auto-imported composables (like `useToast`) as undefined variables in `.vue` files. While TypeScript correctly identified these globals via `auto-imports.d.ts`, the default `no-undef` rule in our Vue ESLint config did not account for them, causing false positive linting errors.
Solution:
- Disable the `no-undef` rule specifically for `.vue` files in `eslint.config.mjs`.
- Rely on TypeScript (via `vue-tsc`) and `auto-imports.d.ts` to handle global variable validation, ensuring type safety without conflicting with the auto-import build process.
- Remove manual imports of `useToast` that were added as a workaround (p sure the path I used didn't even exist in node modules).
This commit addresses several critical stability issues in the notification system spanning the legacy PHP script, the Node.js API, and the Vue frontend.
**Backend / API:**
- **Refactor `notify` script (PHP):** Added `-u` flag to accept a custom filename/ID from the caller. Added filename length sanitization (255 chars) to prevent filesystem errors.
- **Fix ID Mismatch:** The Node API now generates a UUID and passes it to the `notify` script via `-u`. This guarantees that the API, Frontend, and Filesystem all reference the same ID, removing the need for "Risky" notification logic.
- **Fix Counter Bugs:**
- `handleNotificationAdd` no longer ignores duplicate files in the archive.
- `archiveNotification` now checks if a file exists in the archive before moving. If it exists, it simply deletes the unread copy without double-counting.
- `archiveAll` now leverages the robust single-archive logic.
**Frontend (Web):**
- **Fix Infinite Scroll "Drift":**
- Switched `List.vue` to use a **Debounced Refetch** (500ms) for subscription updates instead of manual cache manipulation. This handles rapid-fire events (mass adds) without corruption.
- Increased `pageSize` to `50` to minimize race conditions where new items shift pagination offsets.
- Added **Drift Detection**: If `fetchMore` returns a full page of duplicates (indicating the list has shifted), the component now automatically triggers a full refetch to self-heal.
This change ensures that Nuxt UI notifications respect the display position configured in the legacy webGUI settings.
Backend:
- Added `NotificationSettings` to the GraphQL model.
- Exposed `settings` field on the `Notifications` resolver.
- Implemented `getSettings` in `NotificationsService` to read `notify.position` from the Dynamix store.
Frontend:
- Added `getNotificationSettings` GraphQL query.
- Updated `mount-engine.ts` to fetch settings before mounting.
- Mapped legacy position values (e.g., 'center') to Nuxt UI compatible values (e.g., 'top-center').
Problem this solution addresses:
Basically, when users filtered by alert, warning, or info, results were being paginated first, then filtered by the requested importance, so filtered notifications were not working properly in some (a lot) of cases.
- added a new async generator method to load notifications in batches, enhancing performance and error handling.
- refactored the notification loading logic to utilize the generator, improving readability and maintainability.
- updated filtering logic to streamline the process of matching notifications based on importance and type.
> [!Note] This stubs the unraid-ui/src/components/common/toast. Initially created a shim to convert vue-sonnner toasts to nuxtui. However, since there weren't that many, I just did a clean replacement.
- replace router link with window.location.assign
The `UButton` component attempts to inject the Vue Router instance when the `:to` prop is used. In the standalone component environment (where the router is not installed), this caused a "TypeError: inject(...) is undefined" crash when rendering notifications with links.
This change replaces the `:to` prop with a standard `@click` handler that uses `window.location.assign`, ensuring navigation works correctly without requiring the router context.