Skip to content

feat(farm_onboarding): systray bell + post_init hook autostart#12

Open
dnplkndll wants to merge 4 commits into
19.0from
feat/farm-onboarding-autostart
Open

feat(farm_onboarding): systray bell + post_init hook autostart#12
dnplkndll wants to merge 4 commits into
19.0from
feat/farm-onboarding-autostart

Conversation

@dnplkndll

@dnplkndll dnplkndll commented May 20, 2026

Copy link
Copy Markdown
Contributor

What changed

First slice of the UX-refinement plan (Step 1 of 5). The onboarding wizard now surfaces itself instead of waiting for users to find the menu.

farm_pack

  • New post_init_hook (farm_pack/hooks.py) seeds one farm.onboarding.session per (internal farm user, company) on install. Existing installs upgrade and get the bell immediately; new users get a session lazily. Idempotent — re-runs do not duplicate. Portal users (share=True) and tooling accounts are excluded.
  • Manifest gains the hook reference + version bump 19.0.1.0.0 → 19.0.1.1.0.
  • New farm_pack/tests/test_post_init_hook.py covers: idempotency, fresh-user seeding, portal-user exclusion, multi-company users get one session per company, and users in both portal + farm groups are still excluded.

farm_onboarding

  • First OWL component in the pack: FarmOnboardingSystray (static/src/js/onboarding_systray.esm.js + static/src/xml/onboarding_systray.xml). Leaf icon + red badge dot appears in the navbar when the current user has a pending session. Click → opens the wizard via the existing action_open_for_current_user server action.
  • Component is invisible (t-if) when no session is pending, so non-farm users see nothing. The count_pending_for_current_user RPC is wrapped in try/catch with a state.pending=0 fallback so users without farm_base.group_farm_user don't generate AccessError console spam on every page load.
  • New count_pending_for_current_user @api.model RPC kept separate from get_or_create_for_current_user so the bell's mount path is read-only — it must not create session rows on page load.
  • assets.web.assets_backend block added for the JS + template. First JS assets the pack ships.
  • Manifest version bump 19.0.1.0.0 → 19.0.1.1.0.

Docs

  • farm_onboarding/readme/DESCRIPTION.md + USAGE.md updated to describe the navbar bell as the primary discovery surface.
  • farm_pack/readme/DESCRIPTION.md documents the post_init_hook seeding behavior.
  • First two newsfragments in the pack: farm_onboarding/readme/newsfragments/+systray_bell.feature.md and farm_pack/readme/newsfragments/+post_init_seed.feature.md.
  • README.rst + static/description/index.html regenerated by oca-gen-addon-readme.

Why the .esm.js suffix

The repo's eslint.config.cjs defaults sourceType: script and only treats files matching **/*.esm.js or **/*test.js as ES modules. Using .esm.js is the OCA-standard escape hatch for OWL components in this codebase. Odoo's module loader accepts both naming conventions.

Commits

Four reviewable commits land this PR:

  1. feat(farm_onboarding): systray bell + post_init hook autostart — the feature itself.
  2. fix(farm_onboarding): handle systray RPC failure gracefully — try/catch around the mount-time RPC so users outside farm_base.group_farm_user don't see console errors.
  3. test(farm_onboarding,farm_pack): cover multi-company + portal-overlap edges — two new test cases (multi-company seeding, hybrid portal+farm user excluded) + datetime cleanup.
  4. docs(farm_onboarding,farm_pack): describe systray bell + post_init_hook — README fragments, newsfragments, docstring tighten, log-line clarity.

Tests

  • test_count_pending_for_current_user — verifies 0 when nothing pending, increments on creation, returns to 0 on skip/done.
  • test_post_init_hook.py:
    • test_hook_is_idempotent — re-run on installed db does not duplicate.
    • test_hook_creates_session_for_new_farm_user — fresh user gets seeded.
    • test_hook_skips_portal_users — portal users excluded.
    • test_hook_skips_user_holding_both_portal_and_farm_groups — hybrid users still excluded (share=True wins).
    • test_hook_seeds_one_session_per_company_for_multi_company_user — pins multi-company shape so future refactors don't silently regress.

Test plan

  • CI green on 19.0
  • Smoke install on local doodba (blocked on task #42: workspace odoo container exited OOM in prior session; bring-up still pending). Once that's resolved: install farm_pack against a db with an existing admin user; log in; see the leaf-icon + red dot in the navbar; click; the wizard form opens; complete or skip; reload; bell is gone.

Screenshots

Deferred — the local doodba workspace's odoo container is currently down (industry-packs-odoo-1 exited 137 / OOM, ~30 hours ago). Screenshots will be attached as a PR comment once the smoke-install workstream (task #42) brings the workspace back up. The behavior is fully covered by the server-side tests in the meantime.

What's NOT in this PR (per the plan)

  • Visual design — the bell uses a plain Font Awesome leaf icon + Bootstrap utility classes. Step 2 of the plan (feat/farm-onboarding-design-pass) is the design pass that styles both the bell and the wizard itself.
  • Wizard answers don't yet seed concrete records (Step 3).
  • No QBO-import success state (Step 4) or post-onboarding checklist widget (Step 5).

dnplkndll added 4 commits May 19, 2026 20:42
First UX-refinement slice. Surfaces the onboarding wizard the
moment a farm user signs in instead of waiting for them to find
the menu item.

What's wired:

- `farm_pack` gains a `post_init_hook` that seeds one
  `farm.onboarding.session` per (internal-farm-user, company)
  on install. Existing installs upgrade and immediately surface
  the bell; new users created later pick up a session lazily via
  `get_or_create_for_current_user`.

- `farm_onboarding` ships its first OWL component:
  `FarmOnboardingSystray`. A leaf icon + red badge dot appears in
  the navbar when the current user has a pending session; clicking
  it opens the wizard via the existing `action_open_for_current_user`
  server action. Hidden entirely when no session is pending — non-
  farm users see nothing.

- `farm.onboarding.session.count_pending_for_current_user` is a
  new read-only RPC endpoint the bell calls on mount. Kept separate
  from `get_or_create_for_current_user` so the systray mount path
  cannot accidentally create session rows on every page load.

Step 1 of the UX-refinement plan. Step 2 (the design pass that
gives this bell + the wizard their distinctive look) builds on the
assets pipeline this PR sets up.

Versions bumped: farm_pack 19.0.1.0.0 → 19.0.1.1.0,
farm_onboarding 19.0.1.0.0 → 19.0.1.1.0.
The systray component is registered globally, so it mounts for every
authenticated user — including users without farm_base.group_farm_user.
For those users, count_pending_for_current_user raises AccessError,
which surfaced as an unhandled promise rejection in the browser
console on every page load.

Wrap the RPC in try/catch with a state.pending=0 fallback. The bell
stays hidden (the `t-if` already handles count=0), and the console
stays clean.
… edges

Three test additions/cleanups from the pre-merge review:

- `test_hook_skips_user_holding_both_portal_and_farm_groups` — a user
  in both `base.group_portal` and `farm_base.group_farm_user` has
  `share=True` (set by the portal-group implication). The hook's
  `share=False` filter must exclude them; pin that behavior so a
  future refactor doesn't silently surface the wizard to portal
  accounts that can't actually use it.

- `test_hook_seeds_one_session_per_company_for_multi_company_user` —
  the hook iterates `user.company_ids` and creates one session per
  company. Pin the multi-company shape so a future switch to
  `env.company` would fail loudly.

- Replace `finished_at="2026-01-01"` with `fields.Datetime.now()` in
  the existing `test_count_pending_for_current_user`. The string
  coerces fine through Odoo's ORM but reads as bug-bait.
Captures the review-pass docs gaps:

- `farm_onboarding/readme/DESCRIPTION.md` — adds a "the wizard
  surfaces itself two ways" section covering the navbar bell + the
  menu item, plus a paragraph on the per-user-per-company session
  shape and the install-time seeding done by `farm_pack`.
- `farm_onboarding/readme/USAGE.md` — leads with the navbar bell
  instead of the menu item, mirrors the wizard's actual discovery
  path.
- `farm_pack/readme/DESCRIPTION.md` — documents the new
  `post_init_hook` (what it seeds, who's excluded, idempotency).
- `farm_onboarding/readme/newsfragments/+systray_bell.feature.md`
  and `farm_pack/readme/newsfragments/+post_init_seed.feature.md`
  — first newsfragments in the pack, mirroring OCA changelog
  convention.

Plus two small clean-ups flagged in the review:

- Tighten the docstring on `count_pending_for_current_user`: keep
  the "why separate from get_or_create" rationale, drop the rest.
- Split the `post_init_hook` log line: INFO when something seeded,
  DEBUG on the idempotent quiet path so ops doesn't see
  "seeded 0 onboarding session(s)" on every re-run.

README.rst + static/description/index.html regenerated by
oca-gen-addon-readme to reflect the fragment edits.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant