feat(ui): expand & brand toast notifications (add success level, flash→toast, MokoOnyx theming) #803

Open
opened 2026-07-18 17:25:44 +00:00 by jmiller · 2 comments
Owner

Summary

Expand and brand MokoGIT's client-side toast notification system so transient
user feedback (success/info/warning/error) is delivered consistently through toasts
that match the MokoOnyx design language — instead of the current mix of error-only
toasts and server-rendered flash banners.

Current state

A toast module already exists (web_src/js/modules/toast.ts, web_src/css/modules/toast.css,
built on toastify-js) and exposes:

  • showInfoToast(), showWarningToast(), showErrorToast() — with per-level icon/
    background/duration, preventDuplicates, optional HTML body, and gravity/position/
    duration overrides.
  • hideToastsFrom(), hideToastsAll().

Usage today is heavily error-centric (≈53 showErrorToast calls vs. 6 warning / 6 info),
and there is no success toast at all. Positive, post-action feedback ("Settings saved",
"Branch created", "Copied to clipboard") is still delivered by server-rendered flash
banners
— persistent, layout-shifting, and gone only on the next full page load.

Goals

  1. Add a success level + showSuccessToast() — the one missing intent. Green
    semantic color, checkmark icon, sensible default duration.
  2. Bridge server flash → toast. Convert (or mirror) ctx.Flash success/info/warning/
    error messages into client-side toasts on page load, so post-redirect feedback is
    transient and does not push page content down. Keep a no-JS fallback (render the flash
    banner when JS is unavailable).
  3. Brand the toasts (MokoOnyx). Replace the hardcoded per-level backgrounds in the
    levels map / toast.css with the brand semantic palette and theme tokens so toasts
    follow light/dark:
    • success #448344, danger/error #a51f18, warning #ad6200, info/accent #3f8ff0
    • use Font Awesome 7 glyphs (consistent with the reskin) and --mokogit-shadow elevation.
  4. Broaden adoption for common client-initiated actions where we currently show
    nothing or a flash: copy-to-clipboard, async settings saves, token/secret created,
    webhook test sent, etc.
  5. Accessibility. Ensure the toast container is an aria-live region (polite for
    info/success, assertive for error/warning), toasts are keyboard-dismissible, respect
    prefers-reduced-motion, and never steal focus.

Technical notes

  • Keep the change in web_src/** (JS/CSS) rather than template surgery so it survives
    upstream Gitea merges — same constraint as the theme/reskin work.
  • Extend the ToastLevels map + add the showSuccessToast export in toast.ts; add the
    matching .test.ts case.
  • For flash→toast, read the rendered flash element(s) in a small feature module
    (web_src/js/features/…) and re-emit as toasts, then remove the banner; gate on the
    element existing so no-JS still shows the banner.
  • Align toast.css colors to the theme variables introduced by theme-mokogit-*.css /
    mokogit-brand.css.
  • Related work: theme reskin + FA7 (PR #800 / #802), a11y menu, theme toggle.

Acceptance criteria

  • showSuccessToast() exists, exported, brand-green with a checkmark, and covered by a unit test.
  • All four intents (success/info/warning/error) render with MokoOnyx colors + FA7 icons in both light and dark themes.
  • At least the common success/info flash messages appear as toasts (with a no-JS banner fallback).
  • Toast container is an aria-live region; toasts are dismissible via keyboard; animations respect prefers-reduced-motion.
  • preventDuplicates still works; toasts stack and auto-dismiss on their level duration; hover pauses dismissal.
  • vite build is green and no theme-gitea-* regressions are introduced.

Testing checklist (pre-close — do not close on implementation alone)

  • Trigger a success action (e.g. save a setting) → success toast appears, auto-dismisses, no layout shift.
  • Trigger info/warning/error paths → correct color/icon per level.
  • Verify light theme, dark theme, and auto (system) rendering.
  • Verify with JS disabled → flash banner still shows (fallback intact).
  • Screen-reader announces success/info politely and error/warning assertively.
  • prefers-reduced-motion: reduce disables slide/fade animation.
  • Mobile viewport: toasts don't overlap the navbar and remain dismissible.

Out of scope / follow-ups

  • Real-time/push toasts (websocket-driven notifications) — separate issue.
  • Per-user preference to disable non-error toasts — separate issue.

Authored-by: Moko Consulting

## Summary Expand and brand MokoGIT's client-side **toast notification** system so transient user feedback (success/info/warning/error) is delivered consistently through toasts that match the MokoOnyx design language — instead of the current mix of error-only toasts and server-rendered flash banners. ## Current state A toast module already exists (`web_src/js/modules/toast.ts`, `web_src/css/modules/toast.css`, built on `toastify-js`) and exposes: - `showInfoToast()`, `showWarningToast()`, `showErrorToast()` — with per-level icon/ background/duration, `preventDuplicates`, optional HTML body, and gravity/position/ duration overrides. - `hideToastsFrom()`, `hideToastsAll()`. Usage today is heavily **error-centric** (≈53 `showErrorToast` calls vs. 6 warning / 6 info), and there is **no success toast at all**. Positive, post-action feedback ("Settings saved", "Branch created", "Copied to clipboard") is still delivered by **server-rendered flash banners** — persistent, layout-shifting, and gone only on the next full page load. ## Goals 1. **Add a `success` level + `showSuccessToast()`** — the one missing intent. Green semantic color, checkmark icon, sensible default duration. 2. **Bridge server flash → toast.** Convert (or mirror) `ctx.Flash` success/info/warning/ error messages into client-side toasts on page load, so post-redirect feedback is transient and does not push page content down. Keep a no-JS fallback (render the flash banner when JS is unavailable). 3. **Brand the toasts (MokoOnyx).** Replace the hardcoded per-level backgrounds in the `levels` map / `toast.css` with the brand semantic palette and theme tokens so toasts follow light/dark: - success `#448344`, danger/error `#a51f18`, warning `#ad6200`, info/accent `#3f8ff0` - use Font Awesome 7 glyphs (consistent with the reskin) and `--mokogit-shadow` elevation. 4. **Broaden adoption** for common client-initiated actions where we currently show nothing or a flash: copy-to-clipboard, async settings saves, token/secret created, webhook test sent, etc. 5. **Accessibility.** Ensure the toast container is an `aria-live` region (polite for info/success, assertive for error/warning), toasts are keyboard-dismissible, respect `prefers-reduced-motion`, and never steal focus. ## Technical notes - Keep the change in `web_src/**` (JS/CSS) rather than template surgery so it survives upstream Gitea merges — same constraint as the theme/reskin work. - Extend the `ToastLevels` map + add the `showSuccessToast` export in `toast.ts`; add the matching `.test.ts` case. - For flash→toast, read the rendered flash element(s) in a small feature module (`web_src/js/features/…`) and re-emit as toasts, then remove the banner; gate on the element existing so no-JS still shows the banner. - Align `toast.css` colors to the theme variables introduced by `theme-mokogit-*.css` / `mokogit-brand.css`. - Related work: theme reskin + FA7 (PR #800 / #802), a11y menu, theme toggle. ## Acceptance criteria - [ ] `showSuccessToast()` exists, exported, brand-green with a checkmark, and covered by a unit test. - [ ] All four intents (success/info/warning/error) render with MokoOnyx colors + FA7 icons in both light and dark themes. - [ ] At least the common success/info flash messages appear as toasts (with a no-JS banner fallback). - [ ] Toast container is an `aria-live` region; toasts are dismissible via keyboard; animations respect `prefers-reduced-motion`. - [ ] `preventDuplicates` still works; toasts stack and auto-dismiss on their level duration; hover pauses dismissal. - [ ] `vite build` is green and no `theme-gitea-*` regressions are introduced. ## Testing checklist (pre-close — do not close on implementation alone) - [ ] Trigger a success action (e.g. save a setting) → success toast appears, auto-dismisses, no layout shift. - [ ] Trigger info/warning/error paths → correct color/icon per level. - [ ] Verify light theme, dark theme, and auto (system) rendering. - [ ] Verify with JS disabled → flash banner still shows (fallback intact). - [ ] Screen-reader announces success/info politely and error/warning assertively. - [ ] `prefers-reduced-motion: reduce` disables slide/fade animation. - [ ] Mobile viewport: toasts don't overlap the navbar and remain dismissible. ## Out of scope / follow-ups - Real-time/push toasts (websocket-driven notifications) — separate issue. - Per-user preference to disable non-error toasts — separate issue. --- _Authored-by: Moko Consulting_
Author
Owner

Branch created: feature/803-feat-ui-expand-brand-toast-notifications

git fetch origin
git checkout feature/803-feat-ui-expand-brand-toast-notifications
Branch created: [`feature/803-feat-ui-expand-brand-toast-notifications`](https://git.mokoconsulting.tech/MokoConsulting/MokoGIT/src/branch/feature/803-feat-ui-expand-brand-toast-notifications) ```bash git fetch origin git checkout feature/803-feat-ui-expand-brand-toast-notifications ```
Author
Owner

Folded into the consolidated design on #719 (work package WP-D). Toast colors are already theme-aware; the real gaps are the missing success level (add to Intent + levels, export showSuccessToast + test) and a flash→toast bridge (web_src/js/features/flash-toast.ts re-emitting server .flash-message elements as aria-live toasts, with a no-JS banner fallback). See #719 for the full plan.

Folded into the consolidated design on **#719** (work package **WP-D**). Toast colors are already theme-aware; the real gaps are the missing `success` level (add to `Intent` + `levels`, export `showSuccessToast` + test) and a flash→toast bridge (`web_src/js/features/flash-toast.ts` re-emitting server `.flash-message` elements as aria-live toasts, with a no-JS banner fallback). See #719 for the full plan.
Sign in to join this conversation.